按排序顺序遍历 Javascript 关联数组

IT技术 javascript
2021-03-12 06:38:30

假设我有一个 Javascript 关联数组(又名哈希,又名字典):

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

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

6个回答

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

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

(注意:这在不支持 EcmaScript5 的非常旧的浏览器中不起作用,特别是 IE6、7 和 8。有关详细的最新统计数据,请参阅此表

我喜欢这个,谢谢。这是我利用这个的代码, $(Object.keys(list)).map(function(i,e){return n+'='+list[n];}).get().join('&'); // 连接 url 查询字符串
2021-04-22 06:38:30
@michael667 可能是因为 IE 7 和 8 仍然被广泛使用(不幸的是,谢谢 MS)
2021-04-30 06:38:30
if (!Object.keys) { Object.keys = function (obj) { var op, result = []; for (op in obj) { if (obj.hasOwnProperty(op) { result.push(op) } } return result }
2021-05-10 06:38:30
幸运的是,截至目前,IE7 为 0.5%,IE8 为 8%。
2021-05-11 06:38:30
2016 年更新:这应该是公认的答案
2021-05-13 06:38:30

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

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";
您应该始终检查for循环 if obj.hasOwnProperty(key)
2021-04-26 06:38:30
+1 托罗克。如果答案包含 hasOwnProperty(),那就太好了。
2021-04-28 06:38:30
@Lalit - 如果您指的是 Torok 的评论,那是因为您没有任何干扰对象原型的东西,这是您不能依赖的。
2021-05-15 06:38:30

您甚至可以将其原型化到对象上:

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.5 年前,当我写这个答案时,我有这种感觉,但无论如何还是建议它......感谢提供信息。顺便说一句,它不应该破坏框架,因为它们在迭代对象时应该始终使用 hasOwnProperty
2021-05-02 06:38:30
我赞成这个答案,它看起来不错,但结果证明它破坏了 jquery :( stackoverflow.com/questions/1827458 /... 总的来说,这被认为是一个非常糟糕的主意“你永远不应该扩展 Object.prototype。它的作用远不止于此打破 jQuery;它完全打破了 Javascript 的“对象即哈希表”功能。不要这样做。你可以问约翰·雷西格,他会告诉你同样的事情。”
2021-05-06 06:38:30
这是一个使用值而不是键进行排序的示例同时仍保持key -> value关系。
2021-05-12 06:38:30

我同意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 函数 inArray的回答以了解该问题的答案。所提出的解决方案的一个问题是它a.hasValue('key')会比a['key']. 这在您的代码中可能重要也可能无关紧要。

没有直接操作 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); }
};

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