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

警告:

问题仍然适用于for…of循环。不要用for…in遍历数组,要用它来迭代 在对象的属性上。也就是说,这个


我知道JavaScript中基本的for…in语法是这样的:

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

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

我知道我可能会这样做:

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

或者甚至是美好的老故事:

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

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

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


在Python中,这很简单:

for i, obj in enumerate(myArray):
print i
918737 次浏览

for…in遍历属性名,而不是值,以一种不确定的顺序也是如此(是的,即使在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);
}

< a href = " https://babeljs.io/repl/ ?评估= true&预设= es2015 % 2 cstage-2&代码=函数* % 20列举(iterable) 7 b % 0 a % % 20% 20% 20% 20% 20让% 20我% 20% 3 d % 3 b % 0 a % 0 a % 200% 20% 20% 20% 20 % 20 (const % 20 x % 20 iterable % 20) 7 b % 0 a % % 20% 20% 20% 20% 20% 20% 20% 20% 20收益率% 20% 5 bi % 2 c % 20 x % 5 d % 3 b % 0 a % 20% 20% 20% 20% 20% 20% 20% 20我% 2 b % 2 b % 3 b % 0 a % 20% 20% 20% 20% 7 d % 0 a % 7 d % 0 a % 0 afor % 20 (const % 20% 5 bi % 2 c % 20 obj % % 20列举的5 d % 20 (% 5 b # 39;你好# 39;% 2 c % 20 & # 39; & # 39; % 5 d)) 7 b % 0 a % % 20% 20% 20% 20% 20 console.log(我% 2 c % 20 obj) % 3 b % 0 a % 7 d”rel = " noreferrer " > < >强演示< /强> < / >

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

For-in-loops遍历对象的属性。不要将它们用于数组,即使它们有时有效。

对象属性没有索引,它们都是相等的,不需要按确定的顺序遍历。如果想对属性进行计数,则必须设置额外的计数器(就像在第一个示例中所做的那样)。

循环数组:

var a = [];
for (var i=0; i<a.length; i++) {
i // is the index
a[i] // is the item
}

遍历对象:

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

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

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

如果你想要更简洁的语法,你可以使用forEach:

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

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

小数组集合的解决方案:

for (var obj in arr) {
var i = Object.keys(arr).indexOf(obj);
}

加勒比海盗 - ARRAY, obj -当前元素的键, i -计数器/索引

键()方法在IE版本<9中不可用,您应该使用Polyfill代码。 # EYZ0 < / p >
在ES6中,最好使用for... of循环。 你可以像这样在for... of中获得索引

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

注意,Array.entries()返回一个迭代器,这是允许它在for-of循环中工作的原因;不要将它与Object.entries ()混淆,后者返回键值对的数组

这个怎么样

let numbers = [1,2,3,4,5]
numbers.forEach((number, index) => console.log(`${index}:${number}`))

其中array.forEach这个方法有一个index形参,它是数组中正在处理的当前元素的索引。

这里有一个函数eachWithIndex,它适用于任何可迭代的对象。

您还可以编写一个类似的函数eachWithKey,使用for...in处理对象。

// 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)

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

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

const eachWithIndex = (iterable) => {
return {
*[Symbol.iterator]() {
let i = 0
for(let val of iteratable) {
i++
yield [i, val]
}
}
}


}


const isPrime = (n) => {
for (i = 2; i < Math.floor(Math.sqrt(n) + 1); i++) {
if (n % i == 0) {
return false
}
}
return true
}


let primes = {
*[Symbol.iterator]() {
let candidate = 2
while (true) {
if (isPrime(candidate)) yield candidate
candidate++
}
}
}


for (const [i, prime] of eachWithIndex(primes)) {
console.log(i, prime)
if (i === 100) break
}

rushUp给出的答案是正确的,但这将更方便

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

在每个人发布的非常好的答案之上,我想补充的是,性能最好的解决方案是ES6 entries。这似乎是许多开发者的禁忌,所以我创建了这把手枪

enter image description here

它要快6倍。主要是因为不需要:a)访问数组不止一次,b)强制转换索引。

要在数组上使用for..of循环并检索索引,您可以使用array1.indexOf(element),它将返回循环中元素的索引值。您可以使用此方法同时返回索引和值。

array1 = ['a', 'b', 'c']
for (element of array1) {
console.log(array1.indexOf(element), element) // 0 a 1 b 2 c
}

正如注释中提到的,当数组包含非唯一值时,这将返回false index。(考虑arr = ['a', 'b', 'c', 'a'], arr[3]的索引将返回0而不是3)

// this loop is used in advanced javascript
//For Example I have an array:
let array = [1,2,3,4,5];
1) for(let key in array){
console.log(key);//this shows index of array {Result: 0,1,2,3,4}
console.log(array[key]);//this show values of array {Result: 1,2,3,4,5}
}
//Hopefully, You will quickly understand;