如何按索引顺序迭代稀疏数组?

9
我有一个稀疏数组,其内容没有保证按索引顺序插入,但需要按索引顺序进行迭代。我了解要想遍历稀疏数组,需要使用for..in语句。然而,根据这篇文章的说法:

不能保证for...in会以任何特定的顺序返回索引。

但是像这样的stackoverflow问题表明,虽然对象属性顺序不能保证,但数组顺序可以:

JavaScript中对象的属性顺序不能保证,需要使用Array。

我在最新版本的Chrome、Firefox和IE中进行了测试
<ol id="items"></ol>

var list = [];

function addItem(index) {
    list[index] = { idx : index };
}

var insertOrder = [ 8, 1, 9, 2, 10, 3, 11, 4, 12, 5, 13, 6, 14, 7, 15 ];

for ( var i = 0; i < 15; i++ ) {
    addItem(insertOrder[i]);
}

for(var item in list) {
    $("#items").append("<li>" + list[item].idx + "</li>");
}

所有的内容似乎都按照索引顺序排序,那我能一直信任这种情况吗?否则,我应该如何最好地让它们按照索引顺序排列?


我不会把你引用的那行代码看作是for..in循环在数组中保证顺序的指示。(我并不是说它不保证,但那行代码并没有真正说明它保证了)。此外,即使顺序没问题,也有非常好的理由避免使用for..in循环来迭代数组。 - JLRishe
您可以在此处查看差异:http://jsfiddle.net/abhitalks/rfe33uxf/ - Abhitalks
参考这个答案:此外,规范不保证迭代顺序,这意味着如果你想要“迭代”一个数组对象,使用这个语句时你不能确定属性(数组索引)是否按照数字顺序被访问。 - JLRishe
你的函数 addItem 中,idx 是在哪里定义的? - Ash
2个回答

12

MDN提供了您最初问题的答案:

注意:不应该使用for..in来迭代重要的索引顺序Array。

数组索引只是具有整数名称的可枚举属性,否则与常规对象属性相同。无法保证for...in将以任何特定顺序返回索引,并且它将返回所有可枚举属性,包括那些具有非整数名称和那些被继承的属性。

如果可以的话,您不必使用for..in来遍历稀疏数组,并且应该definitely avoid doing so

您只需使用.forEach即可:

list.forEach(function (el) {  // add a second parameter if you need the indices
    $("#items").append($("<li>").text(el.idx));
});

forEach 被定义 用于按索引顺序迭代并仅包括存在于数组中的元素:

forEach 按升序为数组中每个存在的元素执行提供的回调一次。它不会为已删除或省略的索引调用。但是,对于存在且值为 undefined 的元素,它将被执行。


如果你的目标环境不支持forEach,你可以使用以下代码或MDN页面提供的shim:
for (var i = 0; i < list.length; i += 1) {
    if (i in list) {
        $("#items").append($("<li>").text(list[i].idx));
    }
}

谢谢。而且,这篇文章告诉我ForEach是有保证的。 - Chris Simpson

1
ECMAScript 2015中的for...of结构仅迭代数组数据(而非原型方法),并保证顺序。请参见MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of 和此答案:Does "for...of" loop iteration follow the array order in JavaScript?
请参见Access to ES6 array element index inside for-of loop以检索索引。请注意,for...of会迭代数组中未定义的空洞/空值,因此如果您不想要这些内容,则需要检查key in array
更多讨论请参见:https://groups.google.com/forum/#!topic/strengthen-js/jj7UX-fU-_A - 表明JavaScript缺少有序映射数据结构。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接