简体   繁体   English

Javascript迭代稀疏数组

[英]Javascript iterating through sparse array

I have a sparse array (indexes are not consecutive) like this: 我有一个稀疏数组(索引不连续),如下所示:

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

I would simply like to iterate through each item, do some stuff, and be able to break under a certain condition. 我只想迭代每个项目,做一些事情,并能够在一定条件下休息。

I am fairly new to Javascript and I didn't find a proper way to do it. 我是Javascript的新手,我找不到合适的方法。 Here is what I tried: 这是我尝试过的:

  1. Built-in "for..in". 内置“for..in”。 It seems that this is not the correct way to iterate through an array 看来这不是迭代数组的正确方法

  2. forEach from ECMASCRIPT5. 来自ECMASCRIPT5的forEach This one iterate correctly, but I cannot break from the loop. 这个迭代正确,但我无法摆脱循环。

  3. _.each() from Underscore.js. 来自Underscore.js的_.each() Same result as #2. 与#2相同的结果。

  4. $.each() from JQuery. 来自JQuery的$ .each() With this one I can break by returning false, but it won't iterate correctly. 有了这个,我可以通过返回false来打破,但它不会正确迭代。 For the above example, instead of iterating at 0, 5, 10, 15, it will iterate at 0,1,2,3,4,5,6... which is obviously not what I expect. 对于上面的例子,它不是在0,5,10,15处迭代,而是在0,1,2,3,4,5,6迭代......这显然不是我所期望的。

So my question is: Is there an easy way to iterate a sparse array with the possibility to break during the loop in Javascript or would it be better to use another data structure like an hashtable? 所以我的问题是: 是否有一种简单的方法来迭代稀疏数组,可能在Javascript循环期间中断,或者更好地使用另一种数据结构,如哈希表? If so, any recommandation? 如果有,任何推荐?

Thanks! 谢谢!

What's wrong with the for...in syntax? for...in语法有什么问题? You have an object so the for...in syntax is completely valid to use: 你有一个对象,所以for...in语法完全有效:

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

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

  if (...) {
    break;
  }
}

For..in isn't the worst thing when you're working on an object hash. For..in在处理对象哈希时并不是最糟糕的事情。 It's to be avoided for use with arrays ( [] ), but it should be ok here: 要避免使用数组( [] ),但这里应该没问题:

var val;
for (index in testArray) {
  if (index == 10) {
    break;
  } else {
    val = testArray[index];
  }
}

First thing you have to kiss-bye-bye is "Array". 你要亲吻的第一件事是“阵列”。 There is no real Array in ECMAscript (forgetting about typed-arrays and binary trickery). ECMAscript中没有真正的Array (忘记了类型数组和二进制技巧)。

So what you've got there is a plain Object . 所以你得到的是一个普通的Object To iterate over that, I'd suggest to use .forEach if you're cool with ES5. 为了迭代它,如果你对ES5很酷,我建议使用.forEach If you need to early break that iteration, you might want to use ES5 methods like .some() or .every() , like: 如果您需要提前中断该迭代,您可能需要使用ES5方法,如.some().every() ,如:

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

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

This would interrup the iteration when a key is encountered which numerical value is not lower than 15, by returning true . 当遇到一个数值不低于15的键时,这将通过返回true来中断迭代。

What you have is not an array, it's just an object. 你拥有的不是一个数组,它只是一个对象。

You can test by: 你可以测试:

Array.isArray(testArray)

For what's worth, JavaScript does have array that's said to be sparse. 对于什么是值得的,JavaScript确实有一个据说稀疏的数组。 This happens when you use delete operator to remove an element or change length property to larger. 当您使用delete运算符删除元素或将length属性更改为更大时,会发生这种情况。

To answer your question, to loop thru a object, best way is Object.keys(obj).forEach() . 要回答你的问题,要通过一个对象循环,最好的方法是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);
    }
);

The possible issue with for (var p in o) {…} is that it will also loop thru any enumerable properties in the parent (that is, the prototype chain). for (var p in o) {…}的可能问题是它还将循环通过父级中的任何可枚举属性(即原型链)。 Usually it won't happen though, if you define you object by literal expression var obj = {...} , which by default its parent is Object.prototype, and it doesn't have any enumerable properties. 通常情况下,如果您通过文字表达式var obj = {...}定义对象,默认情况下它的父对象是Object.prototype,并且它没有任何可枚举的属性。

You can also use (abuse) Array.every instead of Array.fromEach to break out of the loop early. 您也可以使用(滥用) 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> 

Basically, Array.every immediately returns false as soon as one of its elements returns false . 基本上, Array.every立即返回false ,只要它的要素之一返回false This lets you break out of the loop early. 这可以让你早点摆脱循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM