Soru JavaScript'de sözdiziminde… için döngü sayacını / dizinini nasıl kullanırsınız?


Dikkat. Bir dizi üzerinde yinelemek için kullanmayın, üzerinde yinelemek için kullanın özellikleri bir nesnenin
Bununla birlikte, bu soru hala döngüler için de geçerli.


Javascript'teki sözdizimi için temelin şuna benzediğini anlıyorum:

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

Ama döngü sayacı / dizinini nasıl alabilirim? Biliyorum, muhtemelen şöyle bir şey yapabilirim:

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

Ya da iyi, eski:

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

Ancak daha basit for-in döngüsünü kullanmayı tercih ederim. Sanırım daha iyi görünüyorlar ve daha mantıklılar.

Ama daha basit veya daha zarif bir yolu var mı?

Python'da bu kolay:

for i, obj in enumerate(myArray):
    print i

133
2018-04-16 18:47


Menşei


Diziler için kullanmayın. Her neyse, özelliklerin değerlerini değil, özellik isimlerini tekrar eder. - Felix Kling
Bu bir dizi değil, bir nesne değil mi? Yani, alert(obj)? - Rocket Hazmat


Cevaplar:


for…in özellik adlarını tekrarlar, değerler değil ve yapar belirtilmemiş bir sırayla (Evet, ES6'dan sonra bile). Diziler üzerinde yinelemek için kullanmamalısınız. Onlar için ES5’ler var forEach Hem değeri hem de dizini, verdiğiniz işleve geçiren yöntem:

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

Veya ES6’lar Array.prototype.entriesŞu anda mevcut tarayıcı sürümleri arasında destek olan:

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

Genel olarak yinelenen yerler için ( for…of bir döngü yerine for…in), yerleşik bir şey yok, ancak:

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);
}

gösteri

Eğer gerçekten demek istedin for…in - numaralandırma özellikleri - ek bir sayaca ihtiyacınız olacaktır. Object.keys(obj).forEach Çalışabilir, ama sadece içerir kendi özellikleri; for…in prototip zincirinin herhangi bir yerinde sayısız mülk içerir.


234
2018-04-16 18:49



Ah tamam. Kafam karışmıştı. JavaScript'in for-in'inin Python'unkiyle aynı olduğunu sanıyordum. Açıklama için teşekkürler. - hobbes3
Aslında, dizi dizi dizini olacaktır, ancak sırayla olduğunu ve diğer özellik isimlerini içermeyeceğine dair bir garanti yoktur. - Felix Kling
var i = 0 yapmanıza gerek yok, çünkü değişmiyorlar mı? - quantumpotato
@quantumpotato: lets varblok kapsamlıdır. constdeğişmez. - Ry-♦
Bunun mümkün olduğunu bilmiyordum: myArray.forEach(function (value, *i*) (vurgu benim). Bu harika. Bundan daha iyi bir yol olması gerektiğini biliyordum. myArray.indexOf(value) çöp yapıyorum. +1. - Braden Best


ES6'da, döngü için kullanmak iyidir. Bunun için indeksi alabilirsin

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

Bunu not et Array.entries() döner bir yineleyiciBu, for-of döngüsünde çalışmasına izin veren şeydir; bununla karıştırmayın Object.entries (), hangi bir döndürür dizi anahtar / değer çiftleri.


78
2017-12-19 11:17



Bu kabul edilenden çok daha iyi bir cevap! - trusktr
Bu çözümün her şeyden daha iyi olduğunu düşünüyorum ... Döngü sözdizimi için adayı kullanır ve ayrı bir işlev kullanmanız gerekmez. Başka bir deyişle, sözdizimi daha iyi. OP bunu istiyor gibi görünüyor. - u8y7541
entries() boş bir nesne döndürüyor: {}. Neden olduğu hakkında bir fikrin var mı? Benim array bir dizi nesnedir. - Joshua Pinter
@JoshuaPinter deneyin Object.entries(array) yerine array.entries() - tonyg
Bunu yapmak gerekiyordu, Joshua - nesne bir yineleyici, bir nesne ile bir next() Her çağrıldığında dizide sonraki girişleri döndürecek yöntem. İçinde hiç (görünür) veri yok; Verileri temel nesneyi arayarak alabilirsiniz. next(), sahnelerin arkasında yapar. cc @tonyg - Shog9♦


Küçük dizi koleksiyonları için çözüm:

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

arr - DİZİ,   obj - Mevcut elemanın anahtarı,   ben - COUNTER / INDEX

Uyarı: Yöntem anahtarlar() IE sürümü <9 için mevcut değil, kullanmalısınız polyfill kodu. https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/keys


15
2018-01-12 09:36



Öneririm: bunun yerine bir sayaç kullanın, döngü içinde artırın. - mayankcpdixit
Mayankcpdixit'e eklendiğinde, bir sayaç kullanın, çünkü indexOf olumsuz bir performans etkisine sahip olabilir. - Dean Liu
Nesne ne kadar büyürse, o kadar yavaş olur. Bu ölçeklendirilmez. - weltschmerz
Bu anlamsız bir şekilde yavaş ve karmaşıktır çünkü var i = 0; ve i++; daha kısa ve daha verimlidir. Ayrıca, mülk sahibi olmayan sayısız mülk için çalışmaz. - Ry-♦
@trusktr: Ve eğer gerekiyorsa… bunu hala kullanmamalısınız. Sadece koleksiyonu değiştirdiğinizde sayacı değiştirin. Yerinde olmak zorunda değilse, bunun yerine güzel bir işlevsel dönüşüm yapın. - Ry-♦


For-in-loop bir Nesnenin özellikleri üzerinde yineleyin. Bazen çalışsalar bile bunları diziler için kullanmayın.

Nesne özellikleri daha sonra hiçbir indekse sahip değildir, hepsi eşittir ve belirli bir sırayla çalıştırılmaları gerekmez. Eğer mülkleri saymak isterseniz, ekstra sayacı (ilk örneğinizde yaptığınız gibi) kurmalısınız.

bir dizi üzerinde döngü:

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

bir nesne üzerinde döngü:

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

11
2018-04-16 18:49



Asla yapma (var i=0; i<a.length; i++) kaynak israfı gibi. kullanım (var i=0, var len = a.length; i<len; i++) - Félix Sanz
@FelixSanz: Atık kaynakları? Asla. Bu, neredeyse hiç gerekli olmayan, erken bir mikro optimizasyon ve var i=0; i<a.length; i++) Zaten her iyi javascript motoru tarafından optimize edilmiş standart döngü modelidir. - Bergi
en iyi uygulamalar en iyi uygulamalardır! - Félix Sanz
ÖPÜCÜK. Gerçekten buna ihtiyacınız olan döngüler yazarsanız, ya yanlış bir şey yapıyorsunuz ya da “en iyi uygulama” dan gerekliliğinden daha iyi bir argümanınız var. Evet, standart bir uygulamadır, ancak genel performans optimizasyonu için değil, sadece mikro optimizasyon için. - Bergi
KISS her yerde geçerlidir. Prematüre optimizasyon bir antrenmandır. - Bergi


Diğerleri söyledikleri gibi, bir dizi üzerinde yinelemek için ... kullanmamalısınız.

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

Temiz sözdizimi istiyorsanız, forEach'i kullanabilirsiniz:

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

Bu yöntemi kullanmak istiyorsanız, eski tarayıcılara destek eklemek için ES5 etiketini eklediğinizden emin olun.


5
2018-04-16 18:55





Buna ne dersin

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

4
2018-02-10 04:17