JavaScript에서 객체의 키/속성 수를 효율적으로 계산하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/126100

문제

객체의 키/속성 수를 계산하는 가장 빠른 방법은 무엇입니까? 물체를 반복하지 않고이 작업을 수행 할 수 있습니까? 즉,하지 않고

var count = 0;
for (k in myobj) if (myobj.hasOwnProperty(k)) count++;

(Firefox는 마법을 제공했습니다 __count__ 속성이지만 이것은 버전 4 주위 어딘가에 제거되었습니다.)

도움이 되었습니까?

해결책

이 작업을 수행합니다 ES5 호환 환경, 와 같은 마디, Chrome, IE 9+, Firefox 4+ 또는 Safari 5+ :

Object.keys(obj).length

다른 팁

이 코드를 사용할 수 있습니다.

if (!Object.keys) {
    Object.keys = function (obj) {
        var keys = [],
            k;
        for (k in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, k)) {
                keys.push(k);
            }
        }
        return keys;
    };
}

그런 다음 이전 브라우저에서도 사용할 수 있습니다.

var len = Object.keys(obj).length;

사용중인 경우 aUNDSCORE.JS 당신이 사용할 수있는 _.크기 (감사합니다 @Douwe) :
_.size(obj)

또는 사용할 수도 있습니다 _.keys 일부는 더 명확 할 수 있습니다.
_.keys(obj).length

나는 많은 기본적인 일을하기위한 타이트한 라이브러리 인 밑줄을 강력히 추천합니다. 가능할 때마다 ECMA5와 일치하고 기본 구현을 연기합니다.

그렇지 않으면 나는 @avi의 답변을지지합니다. ECMA5 브라우저에 추가 할 수있는 Keys () 메소드가 포함 된 MDC DOC에 링크를 추가하기 위해 편집했습니다.

표준 객체 구현 (ES5.1 객체 내부 특성 및 방법)는 필요하지 않습니다 Object 키/속성 수를 추적하려면 Object 열쇠를 명시 적으로 또는 암시 적으로 반복하지 않고.

다음은 가장 일반적으로 사용되는 대안입니다.

1. ecmascript의 Object.keys ()

Object.keys(obj).length; 작품 내부적 키를 반복하여 임시 배열을 계산하고 길이를 반환합니다.

  • 프로 - 읽기 쉽고 깨끗한 구문. 기본 지원을 사용할 수없는 경우 Shim을 제외하고는 라이브러리 또는 사용자 정의 코드가 필요하지 않습니다.
  • 단점 - 배열 생성으로 인한 메모리 오버 헤드.

2. 라이브러리 기반 솔루션

이 주제의 다른 곳에서 많은 도서관 기반 예제는 라이브러리의 맥락에서 유용한 관용구입니다. 그러나 성능 관점에서, 모든 라이브러리 방법이 실제로 For-Loop 또는 ES5를 캡슐화하기 때문에 완벽한 비축 코드와 비교할 때 얻을 수있는 것은 없습니다. Object.keys (기본 또는 반짝임).

3. 루프를 최적화합니다

그만큼 가장 느린 부분 그러한 루프의는 일반적으로입니다 .hasOwnProperty() 함수 호출 오버 헤드로 인해 호출. 그래서 JSON 객체의 항목 수를 원할 때 .hasOwnProperty() 코드가 연장되지 않았다는 것을 알고 있다면 전화하십시오. Object.prototype.

그렇지 않으면 코드가 만들어서 매우 최적화 될 수 있습니다. k 현지의 (var k) 및 접두사 증가 연산자를 사용하여 (++count) postfix 대신.

var count = 0;
for (var k in myobj) if (myobj.hasOwnProperty(k)) ++count;

또 다른 아이디어는 캐싱에 의존합니다 hasOwnProperty 방법:

var hasOwn = Object.prototype.hasOwnProperty;
var count = 0;
for (var k in myobj) if (hasOwn.call(myobj, k)) ++count;

주어진 환경에서 이것이 더 빠르든지 여부는 벤치마킹의 문제입니다. 어쨌든 매우 제한된 성능 이득이 예상 될 수 있습니다.

실제로 성능 문제에 빠지는 경우, 특성을 객체로/제거하는 호출을 객체로/제거하는 호출을 적절하게 명명 된 (크기?) 속성을 증가/감소시키는 호출을 마무리하는 것이 좋습니다.

초기 속성 수를 한 번만 계산하고 그곳에서 계속 이동하면됩니다. 실제 성능 문제가 없다면 귀찮게하지 마십시오. 함수에 해당 코드를 감싸십시오 getNumberOfProperties(object) 그리고 그것으로 끝났습니다.

나는 이것을하는 방법을 알지 못하지만 반복을 최소한으로 유지하기 위해 존재를 확인할 수 있습니다. __count__ 그리고 그것이 존재하지 않는다면 (즉, Firefox가 아님), 당신은 물체를 반복하고 나중에 사용하기 위해 그것을 정의 할 수 있습니다.

if (myobj.__count__ === undefined) {
  myobj.__count__ = ...
}

이런 식으로 모든 브라우저 지원 __count__ 그것을 사용하고, 반복은 그렇지 않은 사람들에 대해서만 수행 될 것입니다. 카운트가 변경 되고이 작업을 수행 할 수 없으면 항상 기능으로 만들 수 있습니다.

if (myobj.__count__ === undefined) {
  myobj.__count__ = function() { return ... }
  myobj.__count__.toString = function() { return this(); }
}

이런 식으로마다 myobj를 참조하십시오.__count__ 이 기능은 발사 및 재 계산됩니다.

Avi Flax에 의해 언급 된 바와 같이 https://stackoverflow.com/a/4889658/1047014

Object.keys(obj).length

객체의 모든 열거 가능한 속성에 대한 트릭을 수행하지만 대신 사용할 수없는 속성을 포함시키기 위해 Object.getOwnPropertyNames. 차이점은 다음과 같습니다.

var myObject = new Object();

Object.defineProperty(myObject, "nonEnumerableProp", {
  enumerable: false
});
Object.defineProperty(myObject, "enumerableProp", {
  enumerable: true
});

console.log(Object.getOwnPropertyNames(myObject).length); //outputs 2
console.log(Object.keys(myObject).length); //outputs 1

console.log(myObject.hasOwnProperty("nonEnumerableProp")); //outputs true
console.log(myObject.hasOwnProperty("enumerableProp")); //outputs true

console.log("nonEnumerableProp" in myObject); //outputs true
console.log("enumerableProp" in myObject); //outputs true

언급 된 바와 같이 여기 이것은 동일한 브라우저 지원이 있습니다 Object.keys

그러나 대부분의 경우 이러한 유형의 작업에 비수기를 포함시키고 싶지는 않지만 차이점을 아는 것이 항상 좋습니다.)

Avi Flax Answer object.keys (obj)를 반복하려면.

예시:

obj = {"lol": "what", owo: "pfft"};
Object.keys(obj).length; // should be 2

~ 대

arr = [];
obj = {"lol": "what", owo: "pfft"};
obj.omg = function(){
    _.each(obj, function(a){
        arr.push(a);
    });
};
Object.keys(obj).length; // should be 3 because it looks like this 
/* obj === {"lol": "what", owo: "pfft", omg: function(){_.each(obj, function(a){arr.push(a);});}} */

이를 피하기위한 단계 :

  1. 키 수를 계산하려는 객체에 함수를 넣지 마십시오.

  2. 별도의 객체를 사용하거나 함수를 위해 특별히 새 개체를 만드십시오 (파일에 얼마나 많은 함수가 있는지 계산하려는 경우 Object.keys(obj).length)

또한 예, 내 예에서 nodejs의 _ 또는 밑줄 모듈을 사용했습니다.

문서는 여기에서 찾을 수 있습니다 http://underscorejs.org/ Github 및 기타 다양한 정보의 출처뿐만 아니라

그리고 마지막으로 lodash 구현 https://lodash.com/docs#size

_.size(obj)

밑줄이있는 사람들은 프로젝트에 포함 된 사람들을 위해 다음을 수행 할 수 있습니다.

_({a:'', b:''}).size() // => 2

또는 기능적 스타일 :

_.size({a:'', b:''}) // => 2

에서: https://developer.mozilla.org/en/docs/web/javascript/reference/global_objects/object/defineproperty

Object.DefineProperty (OBJ, 소품, 설명 자)

모든 개체에 추가 할 수 있습니다.

Object.defineProperty(Object.prototype, "length", {
    enumerable: false,
    get: function() {
        return Object.keys(this).length;
    }
});

또는 단일 객체 :

var myObj = {};
Object.defineProperty(myObj, "length", {
    enumerable: false,
    get: function() {
        return Object.keys(this).length;
    }
});

예시:

var myObj = {};
myObj.name  = "John Doe";
myObj.email = "leaked@example.com";
myObj.length; //output: 2

그런 식으로 추가하면, 루프에 표시되지 않습니다.

for(var i in myObj) {
     console.log(i + ":" + myObj[i]);
}

산출:

name:John Doe
email:leaked@example.com

참고 : <IE9 브라우저에서는 작동하지 않습니다.

위에서 답한대로 : Object.keys(obj).length

그러나 : 우리가 지금 가지고있는 것처럼 지도 ES6의 수업, 나는 할 것이다 제안하다 객체의 속성을 사용하는 대신 사용합니다.

const map = new Map();
map.set("key", "value");
map.size; // THE fastest way

이 문제를 해결 한 방법은 객체에 얼마나 많은 항목이 저장되어 있는지에 대한 기록을 유지하는 기본 목록의 자체 구현을 구축하는 것입니다. 매우 간단합니다. 이 같은:

function BasicList()
{
   var items = {};
   this.count = 0;

   this.add = function(index, item)
   {
      items[index] = item;
      this.count++;
   }

   this.remove = function (index)
   {
      delete items[index];
      this.count--;
   }

   this.get = function(index)
   {
      if (undefined === index)
        return items;
      else
        return items[index];
   }
}

프로젝트에 EXT JS 4가있는 사람들은 다음을 수행 할 수 있습니다.

Ext.Object.getSize(myobj);

이것의 장점은 모든 EXT 호환 브라우저 (IE6-IE8 포함)에서 작동한다는 것입니다. 그러나 다른 제안 된 솔루션과 마찬가지로 실행 시간이 O (N)보다 낫지 않다고 생각합니다.

당신이 사용할 수있는 Object.keys(data).length 키 데이터가있는 JSON 객체의 길이를 찾으려면

위의 jQuery가 작동하지 않으면 시도하십시오

$(Object.Item).length

OP는 객체가 Nodelist인지 지정하지 않았으며, 그렇다면 만 사용할 수 있습니다. 길이 직접 메소드. 예시:

buttons = document.querySelectorAll('[id=button)) {
console.log('Found ' + buttons.length + ' on the screen'); 

나는 이것이 불가능하다고 생각하지 않습니다 (적어도 일부 내부를 사용하지 않고는 아닙니다). 그리고 나는 당신이 이것을 최적화함으로써 많은 것을 얻을 것이라고 생각하지 않습니다.

나는 다음과 같은 모든 객체에 그것을 사용할 수 있도록 노력합니다.

Object.defineProperty(Object.prototype, "length", {
get() {
    if (!Object.keys) {
        Object.keys = function (obj) {
            var keys = [],k;
            for (k in obj) {
                if (Object.prototype.hasOwnProperty.call(obj, k)) {
                    keys.push(k);
                }
            }
            return keys;
        };
    }
    return Object.keys(this).length;
},});

console.log({"Name":"Joe","Age":26}.length) //returns 2

Google Closure는 이것에 대한 좋은 기능을 가지고 있습니다 ... goog.object.getCount (OBJ)

goog.object 문서를보십시오

당신이 사용할 수있는: Object.keys(objectName).length; & Object.values(objectName).length;

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top