使用JavaScript中的语法获取循环计数器/索引

问题描述 投票:199回答:8

Caution:

问题仍然适用于for…of循环。>不要使用for…in迭代数组,使用它来迭代对象的属性。那说,这个


我理解JavaScript中的基本for…in语法如下所示:

for (var obj in myArray) {
    // ...
}

但是如何获得循环计数器/索引?

I know I could probably do something like:

var i = 0;
for (var obj in myArray) {
    alert(i)
    i++
}

Or even the good old:

for (var i = 0; i < myArray.length; i++) {
    var obj = myArray[i]
    alert(i)
}

但我宁愿使用更简单的for-in循环。我认为它们看起来更好,更有意义。

有更简单或更优雅的方式吗?


In Python it's easy:

for i, obj in enumerate(myArray):
    print i
javascript for-loop foreach counter
8个回答
370
投票

for…in迭代属性名称,而不是值,并且in an unspecified order(是的,甚至在ES6之后)。您不应该使用它来迭代数组。对于他们来说,有ES5的forEach方法,它将值和索引传递给你给它的函数:

var myArray = [123, 15, 187, 32];

myArray.forEach(function (value, i) {
    console.log('%d: %s', i, value);
});

// Outputs:
// 0: 123
// 1: 15
// 2: 187
// 3: 32

或ES6的Array.prototype.entries,现在支持当前的浏览器版本:

for (const [i, value] of myArray.entries()) {
    console.log('%d: %s', i, value);
}

对于一般的迭代(你可以使用for…of循环而不是for…in),没有内置的东西,但是:

function* enumerate(iterable) {
    let i = 0;

    for (const x of iterable) {
        yield [i, x];
        i++;
    }
}

for (const [i, obj] of enumerate(myArray)) {
    console.log(i, obj);
}

demo

如果你确实意味着for…in - 枚举属性 - 你需要一个额外的计数器。 Object.keys(obj).forEach可以工作,但它只包括自己的财产; for…in包含原型链上任何位置的可枚举属性。


113
投票

在ES6中,最好使用for-of循环。您可以获得这样的索引

for (let [index, val] of array.entries()) {
        // your code goes here    
}

请注意,Array.entries()返回an iterator,它允许它在for-of循环中工作;不要将此与Object.entries()混淆,for (var obj in arr) { var i = Object.keys(arr).indexOf(obj); } 返回一组键值对。


15
投票

小数组集合的解决方案:

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys

arr - ARRAY,obj - 当前元素的关键字,i - COUNTER / INDEX

注意:方法键()不适用于IE版本<9,您应该使用Polyfill代码。 let numbers = [1,2,3,4,5] numbers.forEach((number, index) => console.log(`${index}:${number}`))


14
投票

这个怎么样

array.forEach

其中index此方法具有var a = []; for (var i=0; i<a.length; i++) { i // is the index a[i] // is the item } 参数,该参数是数组中正在处理的当前元素的索引。


12
投票

For-in-loops迭代Object的属性。不要将它们用于数组,即使它们有时也可以工作。

然后,对象属性没有索引,它们都是相等的,不需要按确定的顺序运行。如果要计算属性,则必须设置额外的计数器(如第一个示例中所示)。

循环数组:

var o = {};
for (var prop in o) {
    prop // is the property name
    o[prop] // is the property value - the item
}

循环对象:

for ( var i = 0, len = myArray.length; i < len; i++ ) { ... }

5
投票

正如其他人所说,你不应该使用for..in迭代数组。

myArray.forEach( function ( val, i ) { ... } );

如果您想要更清晰的语法,可以使用forEach:

eachWithIndex

如果要使用此方法,请确保包含ES5填充程序以添加对旧版浏览器的支持。


0
投票

这是一个函数eachWithKey,适用于任何可迭代的东西。

您还可以编写一个类似的函数qazxsw poi,它使用qazxsw poi处理对象。

for...in

生成器的好处是它们很懒,可以将另一个生成器的结果作为参数。


0
投票

这是我的复合迭代器版本,它通过(慢)素数搜索的示例产生索引和任何传递的生成器函数的值:

// example generator (returns an iterator that can only be iterated once)
function* eachFromTo(start, end) { for (let i = start; i <= end; i++) yield i }

// convers an iterable to an array (potential infinite loop)
function eachToArray(iterable) {
    const result = []
    for (const val of iterable) result.push(val)
    return result
}

// yields every value and index of an iterable (array, generator, ...)
function* eachWithIndex(iterable) {
    const shared = new Array(2)
    shared[1] = 0
    for (shared[0] of iterable) {
        yield shared
        shared[1]++
    }
}

console.log('iterate values and indexes from a generator')
for (const [val, i] of eachWithIndex(eachFromTo(10, 13))) console.log(val, i)

console.log('create an array')
const anArray = eachToArray(eachFromTo(10, 13))
console.log(anArray)

console.log('iterate values and indexes from an array')
for (const [val, i] of eachWithIndex(anArray)) console.log(val, i)
© www.soinside.com 2019 - 2024. All rights reserved.