按排序顺序迭代Javascript关联数组

时间:2009-05-20 23:54:07

标签: javascript

假设我有一个Javascript关联数组(a.k.a.哈希,a.k.a。字典):

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

如何按排序顺序迭代键?如果它有助于简化事情,我甚至不需要这些值(它们都只是数字1)。

10 个答案:

答案 0 :(得分:130)

您可以使用Object.keys内置方法:

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

(注意:这不适用于不支持EcmaScript5的旧版浏览器,特别是IE6,7和8.有关详细的最新统计信息,请参阅this table

答案 1 :(得分:122)

您无法直接迭代它们,但您可以找到所有键,然后对它们进行排序。

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";

答案 2 :(得分: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 :(得分:6)

我同意Swingley's answer,我认为重要的一点是很多这些更精细的解决方案都缺失了。如果您只关心关联数组中的键并且所有值都是'1',那么只需将'keys'作为值存储在数组中。

而不是:

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());

这样做的一个缺点是您无法确定是否轻松设置了特定键。有关该问题的答案,请参阅this answerjavascript function inArray。提出的解决方案的一个问题是a.hasValue('key')将比a['key']略慢。在您的代码中,这可能或不重要。

答案 4 :(得分: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); }
};

为简单起见,这是一个对象定义(而不是可重用的构造函数);随意编辑。

答案 5 :(得分:2)

您可以使用keys库中的underscore.js函数获取密钥,然后使用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);
};

答案 6 :(得分: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]);

答案 7 :(得分: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>

答案 8 :(得分:0)

&#13;
&#13;
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>');
}
&#13;
&#13;
&#13;

答案 9 :(得分:0)

我非常喜欢@ luke-schafer的原型创意,但也听到了他对原型问题的看法。使用简单的功能怎么样?

&#13;
&#13;
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);
&#13;
&#13;
&#13;

这似乎消除了原型的问题,仍然为对象提供了一个排序的迭代器。我不是一个真正的JavaScript大师,所以我很想知道这个解决方案是否隐藏了我错过的缺陷。