정렬 된 순서로 Javascript 연관 배열을 반복합니다.


109

Javascript 연관 배열 (일명 해시, 일명 사전)이 있다고 가정 해 보겠습니다.

var a = new Array();
a['b'] = 1;
a['z'] = 1;
a['a'] = 1;

정렬 된 순서로 키를 어떻게 반복 할 수 있습니까? 일을 단순화하는 데 도움이된다면 값도 필요하지 않습니다 (모두 숫자 1 일뿐입니다).


11
왜 new Array () 구문을 사용하고 객체처럼 사용하고 있습니까?
Luke Schafer

@Luke .. PHP 배경에서 나도 처음에 이것을했습니다. 나는 지금 배웠습니다 :)
alex

20
@Luke : '나는 경험이없는 것 같다. 답변에 올바른 방법을 게시 할 수 있습니까?
mike

4
간단하게 모든 개체를 만들 수 있습니다. 자바 스크립트에서는 사전 / "명명 된 배열"과 일반 객체간에 차이가 없습니다. 따라서 ab로 a [ 'b']에 액세스 할 수 있으며 그 반대의 경우도 마찬가지입니다. 객체를 만드는 가장 짧은 방법은 a = {};입니다.
Lodewijk

답변:


124

직접 반복 할 수는 없지만 모든 키를 찾은 다음 정렬 할 수 있습니다.

var a = new Array();
a['b'] = 1;
a['z'] = 1;
a['a'] = 1;    

function keys(obj)
{
    var keys = [];

    for(var key in obj)
    {
        if(obj.hasOwnProperty(key))
        {
            keys.push(key);
        }
    }

    return keys;
}

keys(a).sort(); // ["a", "b", "z"]

그러나 변수 'a'를 배열로 만들 필요는 없습니다. 당신은 정말로 그것을 객체로 사용하고 있으며 다음과 같이 만들어야합니다.

var a = {};
a["key"] = "value";

28
인 경우 항상 for루프를 확인해야 합니다 obj.hasOwnProperty(key).
viam0Zah

3
@Lalit-Torok의 의견을 언급하는 경우, 그것은 의지 할 수없는 객체의 프로토 타입을 방해하는 것이 없기 때문입니다.
Luke Schafer

1
Torok +1. 대답에 hasOwnProperty ()가 포함되어 있으면 좋을 것입니다.
Jon Onstott 2011 년

136

Object.keys 내장 메서드를 사용할 수 있습니다 .

var sorted_keys = Object.keys(a).sort()

(참고 : EcmaScript5, 특히 IE6, 7 및 8을 지원하지 않는 매우 오래된 브라우저에서는 작동하지 않습니다. 자세한 최신 통계는 이 표를 참조하십시오. )


@ IE 7과 8이 여전히 널리 사용되기 때문에 michael667 아마 (불행히도, 당신에게 MS 감사)
알렉산더 Reifinger

1
다행히 현재 IE7은 0.5 %이고 IE8은 8 %입니다.
molnarg 2013

3
if (!Object.keys) { Object.keys = function (obj) { var op, result = []; for (op in obj) { if (obj.hasOwnProperty(op) { result.push(op) } } return result }
Jordan Reiter 2013

나는 이것을 사랑합니다, 감사합니다. 다음은 이것을 활용하는 코드입니다. $ (Object.keys (list)). map (function (i, e) {return n + '='+ list [n];}). get (). join ( '&'); // URL 쿼리 문자열 연결
Elaine

1
2016 업데이트 : 이것은 아마도 받아 들여진 대답이어야합니다
rinogo

14

객체에 프로토 타입을 만들 수도 있습니다.

Object.prototype.iterateSorted = function(worker)
{
    var keys = [];
    for (var key in this)
    {
        if (this.hasOwnProperty(key))
            keys.push(key);
    }
    keys.sort();

    for (var i = 0; i < keys.length; i++)
    {
        worker(this[ keys[i] ]);
    }
}

및 사용법 :

var myObj = { a:1, b:2 };
myObj.iterateSorted(function(value)
{
    alert(value);
} 

3
나는이 대답을 upvoted 그것은 꽤 좋은 것처럼 보였지만 jquery :( stackoverflow.com/questions/1827458/… 그리고 일반적으로 매우 나쁜 생각으로 간주됩니다. "Object.prototype을 확장해서는 안됩니다. ... jQuery를 파괴, 완전히 자바 스크립트의 "개체로서의 해시 테이블"기능을 중단하지 마 당신은 존 레식을 요청할 수 있습니다, 그는 당신에게 같은 일을 말해주지 "
msanjay

그거 알아? 나도 프로토 타입이 싫다. :) 절대 사용하지 않고 적극적으로 사용을 권장하지 않는다. 3.5 년 전 제가이 답변을 썼을 때 이런 느낌을 받았지만 어쨌든 제안했습니다 ... 정보를 제공해 주셔서 감사합니다. 반복하는 객체를 할 때 항상 hasOwnProperty를 사용해야로 제쳐두고, 그것은 프레임 워크를 중단해서는 안
누가 복음 쉐퍼을

다음은 관계를 유지하면서 정렬위해 키 대신 값을 사용하는 예 key -> value입니다.
Xeoncross

6

나는 Swingley의 답변에 동의하며 더 정교한 솔루션이 많이 누락되어 중요한 점이라고 생각합니다. 연관 배열의 키에만 관심이 있고 모든 값이 '1'이면 '키'를 배열의 값으로 저장하면됩니다.

대신에:

var a = { b:1, z:1, a:1 };
// relatively elaborate code to retrieve the keys and sort them

사용하다:

var a = [ 'b', 'z', 'a' ];
alert(a.sort());

한 가지 단점은 특정 키가 쉽게 설정되었는지 여부를 확인할 수 없다는 것입니다. 이 문제에 대한 답변javascript function inArray에 대한 답변 을 참조하십시오 . 제시된 솔루션의 한 가지 문제 a.hasValue('key')a['key']. 그것은 당신의 코드에서 중요하거나 중요하지 않을 수 있습니다.


3

Javascript 객체의 "키"를 직접 조작하는 간결한 방법은 없습니다. 그것은 실제로 그것을 위해 설계되지 않았습니다. 일반 객체 (또는 샘플 코드에서 알 수 있듯이 배열)보다 더 나은 데이터를 자유롭게 배치 할 수 있습니까?

그렇다면 질문이 "정렬 된 순서로 키를 반복하려면 어떤 사전과 같은 객체를 사용해야합니까?"로 다시 표현 될 수 있습니다. 다음과 같은 객체를 개발할 수 있습니다.

var a = {
  keys : new Array(),
  hash : new Object(),
  set : function(key, value) {
    if (typeof(this.hash[key]) == "undefined") { this.keys.push(key); }
    this.hash[key] = value;
  },
  get : function(key) {
    return this.hash[key];
  },
  getSortedKeys : function() {
    this.keys.sort();
    return this.keys;
  }
};

// sample use
a.set('b',1);
a.set('z',1);
a.set('a',1);
var sortedKeys = a.getSortedKeys();
for (var i in sortedKeys) { print(sortedKeys[i]); }

데이터가 일반 객체에 있다는 사실을 제어 할 수없는 경우이 유틸리티는 일반 객체를 완전한 기능의 사전으로 변환합니다.

a.importObject = function(object) {
  for (var i in object) { this.set(i, object); }
};

이것은 단순성을 위해 객체 정의 (재사용 가능한 생성자 함수 대신)였습니다. 마음대로 편집하십시오.


2

첫 번째 for루프 에서 키를 가져 와서 정렬하고, 두 번째 for루프 에서 정렬 된 결과를 사용합니다 .

var a = new Array();
a['b'] = 1;
a['z'] = 1;
a['a'] = 1;

var b = [];
for (k in a) b.push(k);
b.sort();
for (var i = 0; i < b.length; ++i) alert(b[i]);

2

underscore.js 라이브러리 의 keys함수를 사용하여 키를 가져온 다음 배열 메서드를 사용하여 정렬 할 수 있습니다.sort()

var sortedKeys = _.keys(dict).sort();

keys밑줄의 소스 코드의 기능 :

// Retrieve the names of an object's properties.
// Delegates to **ECMAScript 5**'s native `Object.keys`
_.keys = nativeKeys || function(obj) {
    if (obj !== Object(obj)) throw new TypeError('Invalid object');
    var keys = [];
    for (var key in obj) if (_.has(obj, key)) keys.push(key);
    return keys;
};    

// Shortcut function for checking if an object has a given property directly
// on itself (in other words, not on a prototype).
_.has = function(obj, key) {
    return hasOwnProperty.call(obj, key);
};

0
<script type="text/javascript">
    var a = {
        b:1,
        z:1,
        a:1
    }; // your JS Object
    var keys = [];
    for (key in a) {
        keys.push(key);
    }
    keys.sort();
    var i = 0;
    var keyslen = keys.length;
    var str = '';
    //SORTED KEY ITERATION
    while (i < keyslen) {
        str += keys[i] + '=>' + a[keys[i]] + '\n';
        ++i;
    }
    alert(str);
    /*RESULT:
    a=>1
    b=>1
    z=>1
    */
</script>

0

var a = new Array();
a['b'] = 1;
a['z'] = 1;
a['a'] = 1;


var keys=Object.keys(a).sort();
for(var i=0,key=keys[0];i<keys.length;key=keys[++i]){
  document.write(key+' : '+a[key]+'<br>');
}


0

저는 @ luke-schafer의 프로토 타입 아이디어를 정말 좋아하지만 프로토 타입 문제에 대해 그가 말하는 것도 듣습니다. 간단한 기능을 사용하는 것은 어떻습니까?

function sortKeysAndDo( obj, worker ) {
  var keys = Object.keys(obj);
  keys.sort();
  for (var i = 0; i < keys.length; i++) {
     worker(keys[i], obj[keys[i]]);
  }
}

function show( key, value ) {
  document.write( key + ' : ' + value +'<br>' );
}

var a = new Array();
a['b'] = 1;
a['z'] = 1;
a['a'] = 1;

sortKeysAndDo( a, show);

var my_object = { 'c': 3, 'a': 1, 'b': 2 };

sortKeysAndDo( my_object, show);

이것은 프로토 타입의 문제를 제거하고 여전히 객체에 대해 정렬 된 반복자를 제공하는 것처럼 보입니다. 하지만 저는 JavaScript 전문가가 아니기 때문에이 솔루션에 제가 놓친 숨겨진 결함이 있는지 알고 싶습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.