13

我有一个稀疏数组(索引不连续),如下所示:

var testArray = { 0: "value1", 5: "value2", 10: "value3", 15: "value4" };

我只想遍历每个项目,做一些事情,并能够在特定条件下中断。

我对 Javascript 还很陌生,但没有找到合适的方法。这是我尝试过的:

  1. 内置“for..in”。似乎这不是遍历数组的正确方法

  2. 来自 ECMASCRIPT5 的forEach 。这一个迭代正确,但我无法脱离循环。

  3. _.each()来自 Underscore.js。结果与#2 相同。

  4. $.each()来自 JQuery。有了这个,我可以通过返回 false 来中断,但它不会正确迭代。对于上面的例子,不是在 0、5、10、15 处迭代,而是在 0、1、2、3、4、5、6 处迭代……这显然不是我所期望的。

所以我的问题是:有没有一种简单的方法来迭代稀疏数组,并有可能在 Javascript 中的循环期间中断,或者使用其他数据结构(如哈希表)会更好吗?如果有,有什么推荐吗?

谢谢!

4

5 回答 5

10

for...in语法有什么问题?您有一个对象,因此for...in语法完全可以使用:

var testArray = { 0: "value1", 5: "value2", 10: "value3", 15: "value4" };

for (var key in testArray) {
  var value = testArray[key];

  if (...) {
    break;
  }
}
于 2012-05-13T03:32:26.023 回答
3

For..in 在处理对象哈希时并不是最糟糕的事情。应避免与数组 ( []) 一起使用,但在这里应该没问题:

var val;
for (index in testArray) {
  if (index == 10) {
    break;
  } else {
    val = testArray[index];
  }
}
于 2012-05-13T03:33:01.143 回答
3

你所拥有的不是一个数组,它只是一个对象。

您可以通过以下方式进行测试:

Array.isArray(testArray)

值得一提的是,JavaScript 确实有据说是稀疏的数组。当您使用delete运算符删除元素或将长度属性更改为更大时,就会发生这种情况。

要回答您的问题,通过对象循环,最好的方法是Object.keys(obj).forEach().

var o = {"a":3, "b":4};

Object.keys(o).forEach(
    function (key) {
        var val = o[key];
        console.log("Key:" + key);
        console.log("Value:" + val);
    }
);

可能的问题 for (var p in o) {…}是它还将循环遍历父级(即原型链)中的任何可枚举属性。但是,通常它不会发生,如果您通过字面表达式定义对象var obj = {...},默认情况下它的父对象是 Object.prototype,并且它没有任何可枚举的属性。

于 2016-04-20T21:17:51.287 回答
2

你必须吻别的第一件事是“阵列”。ECMAscript中没有真正Array的东西(忘记类型数组和二进制技巧)。

所以你得到的是一个普通的Object. .forEach要迭代它,如果你对 ES5 很满意,我建议你使用。如果您需要提前中断该迭代,您可能需要使用 ES5 方法,例如.some()or .every(),例如:

Object.keys( testArray ).some(function( key ) {
    if( +key < 15 ) {            
        return true;
    }

    console.log(key, testArray[key]);
});

当遇到一个数值不低于 15 的键时,这将通过返回 来中断迭代true

于 2012-05-13T03:36:08.443 回答
1

您也可以使用 (abuse)Array.every代替Array.fromEach提前跳出循环。

var pre = document.getElementById('console');

var arr = new Array();
arr[10] = 'Hello';
arr[20] = 'World!';
arr[30] = 'stop';
arr[40] = 'Goodbye';

arr.every(function (val, idx) {
  if (val !== 'stop') {
    pre.textContent += idx+': '+val+'\n';
    return true;
  }
});
<pre id="console"></pre>

基本上,只要其中一个元素返回,就会Array.every立即返回。这使您可以尽早跳出循环。falsefalse

于 2019-02-24T00:25:15.557 回答