for-ofループ内のES6配列要素インデックスへのアクセス


227

for-ofループを使用して配列要素にアクセスできます。

for (const j of [1, 2, 3, 4, 5]) {
  console.log(j);
}

このコードを変更して現在のインデックスにもアクセスするにはどうすればよいですか?forEachでもfor-inでもないfor-of構文を使用してこれを実現したいと思います。

回答:


348

使用Array.prototype.keys

for (const index of [1, 2, 3, 4, 5].keys()) {
  console.log(index);
}

キーと値の両方にアクセスする場合はArray.prototype.entries()destructuringで使用できます。

for (const [index, value] of [1, 2, 3, 4, 5].entries()) {
  console.log(index, value);
}


64
誰かが不思議に思った場合、私はでテストfor-ofしましたが.entries()、に比べて2倍遅い.forEach()です。jsperf.com/for-of-vs-foreach-with-index

1
あなたはESで最速を持つようにしたいかどうかを知るためにK48の素敵な@、使用することは、「forループ逆転」:incredible-web.com/blog/...
nimo23

3
残念ながら、ネストされたループの内側から譲る必要があります。関数がyieldキーワードのスコープの問題を作成するため、forEachを使用できません。しかし、私はユースケースのインデックスにアクセスする必要があるので、...基本的な古い;;ループはそうです。
カイルベイカー

2
@KyleBakerそして、for-ofループの何が問題になってい.entires()ますか?
のMichałPerłakowski

1
代わりに逆ループでは、長さjsperf.com/reverse-loop-vs-cacheをキャッシュできます。RAMに大きな配列を作成せずにストリームを処理できる場合の反復可能な処理に役立つ。このような場合、I / Oレイテンシが発生するため、ループ速度はボトルネックにはなりません。
x'ES

289

Array#entries 両方が必要な場合は、インデックスと値を返します。

for (let [index, value] of array.entries()) {

}

3
TypeScriptの場合: 'TS2495:Type IterableIterator is not a array type or a string type' これは解決されるようです:github.com/Microsoft/TypeScript/pull/12346
Johannes

2
また、Internet Explorerはサポートされていません。
Sammi 2017年

1
よくない。エラーをスローします。たとえば、他の多くのDOM反復可能構造を使用しdocument.styleSheets[0].cssRules.entries()たり、場合によってはエラーをスローしたりしdocument.styleSheets.entries()ます。それでも使用する必要があります_.forEach()からlodash
スティーブンPribilinskiy

2
@Steven:インデックスが必要ない場合は、実行してくださいfor (var value of document.styleSheets) {}。あなたは、インデックスが必要な場合、あなたはを介して第一の配列に値を変換することができますArray.fromfor (let [index, value] of Array.from(document.styleSheets)) {}
Felix Kling 2017年

1
それはすばらしい!Array.fromはFTWです
Steven Pribilinskiy 2017年

28

派手な新しいネイティブ関数のこの世界では、基本を忘れることがあります。

for (let i = 0; i < arr.length; i++) {
    console.log('index:', i, 'element:', arr[i]);
}

クリーンで効率的でbreak、ループを継続できます。ボーナス!最後から始めて、i--

追記:ループ内で値を頻繁に使用している場合はconst value = arr[i];、簡単で読みやすい参照のためにループの先頭で実行することをお勧めします。


1
うん。いいですね、明快でシンプル。ああ、それと同じように、配列のキー/インデックスにアクセスする非常に簡単な方法があります。
2018年

2
ちなみに、条件は次のようになります-> for(let i = 0; i <arr.length; i ++)(-1)がない場合、配列のすべての要素をループしません。
2018年

1
@Combine Good catch!私はあなたのメモを反映するために私の答えを更新しました。
chris

4
あなたはまだすることができかつ読みはるかに簡単です。後退は追加と同じくらい簡単です。breakfor-offor (let [index, value] of array.entries()).reverse()
Nigel B. Peck

2
これはこの質問に対する完全に受け入れられる答えだと思います。決して受け入れられる答えにはなりませんが、この質問を検索した数十人以上の人を助けてきました。これがSOの目的です。
ダノラム

3

html / jsコンテキストでは、最新のブラウザーで、配列以外の反復可能なオブジェクトを使用して、[Iterable] .entries()を使用することもできます。

for(let [index, element] of document.querySelectorAll('div').entries()) {

    element.innerHTML = '#' + index

}

はい、これは機能しますが、@ Steven Pribilinskiyによって前述した他のDOMメソッドは、entriesメソッドを持たないオブジェクトを返します。
Matanster

3

for..ofループ我々はこれを経由して達成することができますarray.entries()array.entries新しい配列反復子オブジェクトを返します。イテレータオブジェクトは、そのシーケンス内の現在の位置を追跡しながら、一度にイテラブルオブジェクトからアイテムにアクセスする方法を知っています。

ときにnext()メソッドがイテレータのキーと値のペアで呼び出され、生成されます。これらのキーと値のペアでは、配列インデックスがキーであり、配列アイテムが値です。

let arr = ['a', 'b', 'c'];
let iterator = arr.entries();
console.log(iterator.next().value); // [0, 'a']
console.log(iterator.next().value); // [1, 'b']

for..ofループは、基本的に反復可能を消費し(フード下反復子を使用して)すべての要素をループ構築物です。これをarray.entries()次の方法で組み合わせることができます。

array = ['a', 'b', 'c'];

for (let indexValue of array.entries()) {
  console.log(indexValue);
}


// we can use array destructuring to conveniently
// store the index and value in variables
for (let [index, value] of array.entries()) {
   console.log(index, value);
}


3

また、あなたが必要な場合は、インデックスを自分で処理することができ、インデックスをあなたが必要とする場合、それは動作しませんキーを

let i = 0;
for (const item of iterableItems) {
  // do something with index
  console.log(i);

  i++;
}

0

ないオブジェクト使用してそれらのためにArrayあなたはまだ使用できるように、あなたが簡単に独自のiterableを構築することができ、配列のような、あるいはfor ofのようなもののためにlocalStorage実際には持っているがlength

function indexerator(length) {
    var output = new Object();
    var index = 0;
    output[Symbol.iterator] = function() {
        return {next:function() {
            return (index < length) ? {value:index++} : {done:true};
        }};
    };
    return output;
}

次に、それに数値を入力します。

for (let index of indexerator(localStorage.length))
    console.log(localStorage.key(index))

0

es6 for...in

for(const index in [15, 64, 78]) {                        
    console.log(index);
}

5
質問が尋ねているfor...ofループではないfor...in
エイブラハム・ヘルナンデス

3
for...inは、元のECMAScript仕様(つまり、「es1」)の一部です。また、これfor...inはオブジェクトのプロパティを反復するためのものです。配列を反復することはできますが、期待した順序で反復しない場合があります。MDNドキュメント
Boaz

0

別のアプローチArray.prototype.forEach()としては

Array.from({
  length: 5
}, () => Math.floor(Math.random() * 5)).forEach((val, index) => {
  console.log(val, index)
})


-6
var fruits = ["apple","pear","peach"];
for (fruit of fruits) {
    console.log(fruits.indexOf(fruit));
    //it shows the index of every fruit from fruits
}

forループは配列をトラバースしますが、indexofプロパティは配列に一致するインデックスの値を取ります。PDこの方法にはいくつかの欠点があるため、果物を使用してください


2
これにはO(n ^ 2)時間かかります。
ハリー

3
パフォーマンスが重要でない場合でも、重複した果物がある場合、これはまだすべての正しいインデックスを提供しません。たとえば、指定され["apple", "apple", "pear"]たインデックスはの0, 0, 2代わりに0, 1, 2です。
trichoplax
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.