web-dev-qa-db-ja.com

JavaScriptで配列をループする

Javaでは、forループを使用して、次のように配列内のオブジェクトを走査できます。

String[] myStringArray = {"Hello", "World"};
for (String s : myStringArray)
{
    // Do something
}

JavaScriptでも同じことができますか。

2640
Mark Szymanski

シーケンシャルなforループを使う:

var myStringArray = ["Hello","World"];
    var arrayLength = myStringArray.length;
    for (var i = 0; i < arrayLength; i++) {
        console.log(myStringArray[i]);
        //Do something
    }

@zipcodemanはfor...inステートメントの使用を推奨しますが、配列を反復するためにfor-inは避けるべきです、そのステートメントは 列挙 オブジェクトプロパティを意味します。

次の理由で、これは配列のようなオブジェクトには使用しないでください。

  • 繰り返しの順序は保証されていません、配列インデックスは数値順に訪問されないかもしれません。
  • 継承されたプロパティも列挙されています。

2つ目のポイントは、Array.prototypeオブジェクトを拡張してそこにメソッドを含めると、そのプロパティも列挙されるなど、多くの問題が発生する可能性があることです。

例えば:

Array.prototype.foo = "foo!";
    var array = ['a', 'b', 'c'];
    
    for (var i in array) {
      console.log(array[i]);
    }

上記のコードは、 "a"、 "b"、 "c"、および "foo!"をコンソール化します。

ネイティブのプロトタイプ拡張に大きく依存しているライブラリを使用している場合(例えばMooToolsなど)、これは特に問題になります。

前に述べたfor-inステートメントには、enumerateオブジェクトのプロパティがあります。次に例を示します。

var obj = {
      "a": 1,
      "b": 2,
      "c": 3
    };

    for (var prop in obj) {
      if (obj.hasOwnProperty(prop)) { 
      // or if (Object.prototype.hasOwnProperty.call(obj,prop)) for safety...
        console.log("prop: " + prop + " value: " + obj[prop])
      }
    }

上記の例ではhasOwnPropertyメソッドはown propertiesだけを列挙することを可能にします、それはそれがオブジェクトに物理的に持っているプロパティだけであり、継承されたプロパティではありません。

次の記事を読むことをお勧めします。

3268
CMS

はい、あなたの実装が ECMAScript 2015 ( "Harmony"リリース)で導入されたfor...of機能を含んでいると仮定すると...これは最近かなり安全な仮定です。

それはこのように動作します:

// REQUIRES ECMASCRIPT 2015+
var s, myStringArray = ["Hello", "World"];
for (s of myStringArray) {
  // ... do something with s ...
}

さらに良いことに、ECMAScript 2015はletconstを介してブロックスコープ変数も提供しています。

// REQUIRES ECMASCRIPT 2015+
const myStringArray = ["Hello", "World"];
for (const s of myStringArray) {
  // ... do something with s ...
}
// s is no longer defined here

JavaScript開発者の中にはまだ、まだそこにない環境で作業している人がいます - 特にWebブラウザで実行するコードを書く場合、サイト開発者はクライアントがどのブラウザ/バージョンを使うのかわからないことが多いです。

JavaScriptインタプリタがECMAScript仕様のpreviousエディション(たとえば、9より前のバージョンのInternet Explorer)に準拠していると想定できる場合は、代わりにforEachイテレータメソッドを使用できます。ループ。その場合は、配列内の各項目で呼び出される関数を渡します。

var myStringArray = [ "Hello", "World" ];
myStringArray.forEach( function(s) { 
     // ... do something with s ...
} );

しかし、それでも想定するには多すぎて、allバージョンのJavaScriptで機能するものが必要な場合は、明示的なカウントループを使用する必要があります。スパース配列を適切に処理する最も安全なバージョンは、次のようなものです。

var i, s, myStringArray = [ "Hello", "World" ], len = myStringArray.length;
for (i=0; i<len; ++i) {
  if (i in myStringArray) {
    s = myStringArray[i];
    // ... do something with s ...
  }
}

(ループ条件に完全なmyStringArray.length式を含めるのではなく)ローカル変数に長さの値を割り当てると、毎回プロパティの検索がスキップされるため、パフォーマンスに大きな違いが生じる可能性があります。私のマシンでRhinoを使うと、スピードアップは43%です。 

このように、ループ初期化節で長さキャッシュが行われることがよくあります。

var i, len, myStringArray = [ "Hello", "World" ];
for (len = myStringArray.length, i=0; i<len; ++i) {

他の人が言及したfor...inの構文は、オブジェクトのプロパティをループするためのものです。 JavaScriptのArrayは単に数値のプロパティ名を持つオブジェクト(および自動的に更新されるlengthプロパティ)なので、理論的にはそれを使ってArrayをループすることができます。しかし、問題は、それ自体が数値プロパティ値に限定されず(メソッドでも実際には値がクロージャであるプロパティであることに注意してください)、数値順に繰り返されることもありません。したがって、for...in構文は、配列をループするためにnotを使用する必要があります。 

998
Mark Reed

mapを使うことができます。これは PythonHaskell のような他の言語でも利用可能な関数型プログラミング手法です。

[1,2,3,4].map( function(item) {
     alert(item);
})

一般的な構文は次のとおりです。

array.map(func)

一般的にfuncは1つのパラメータを取ります。それは配列の要素です。しかしJavaScriptの場合、アイテムのインデックスである2番目のパラメータと、配列そのものである3番目のパラメータを取ります。

array.mapの戻り値は別の配列なので、このように使用できます。

var x = [1,2,3,4].map( function(item) {return item * 10;});

そして今xは[10,20,30,40]です。

関数をインラインで書く必要はありません。それは別の機能かもしれません。

var item_processor = function(item) {
      // Do something complicated to an item
}

new_list = my_list.map(item_processor);

これは次のようなものに相当します。

 for (item in my_list) {item_processor(item);}

あなたがnew_listを取得しないのを除いて。

415
hasen

JavaScriptでは、for-inループでArrayをループすることはお勧めできませんが、次のようにforループを使用することをお勧めします。

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

それは同様に最適化されています(配列の長さを「キャッシュする」)。もっと学びたいのであれば、 この件についての私の投稿を読んでください

107
sebarmeli

for(var s of myStringArray){

(直接あなたの質問に答える:今あなたはできる!)

他のほとんどの答えは正しいですが、彼らは(この記事の執筆時点で)ECMA Script)については言及していません。 6 2015は繰り返しを行うための新しいメカニズム、for..ofループをもたらしています。 

この新しい構文は、JavaScriptで配列を反復するための最もエレガントな方法です(反復インデックスが必要ない限り)が、ブラウザではまだ広くサポートされていません。 

現在Firefox 13以降、Chrome 37以降で動作し、他のブラウザでは本来動作しません(下記のブラウザの互換性を参照)。幸いなことに、今日の次世代機能を使えるようにするJSコンパイラ( Babel など)があります。

これはNodeでも動作します(私はバージョン0.12.0でテストしました)。

配列を繰り返す

// You could also use "let" instead of "var" for block scope.
for (var letter of ["a", "b", "c"]) { 
   console.log(letter); 
}

オブジェクトの配列を繰り返す

var band = [
  {firstName : 'John', lastName: 'Lennon'}, 
  {firstName : 'Paul', lastName: 'McCartney'}
];

for(var member of band){
  console.log(member.firstName + ' ' + member.lastName); 
}

ジェネレータを繰り返す:

(例は https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of から抽出された)

function* fibonacci() { // a generator function
  let [prev, curr] = [1, 1];
  while (true) {
    [prev, curr] = [curr, prev + curr];
    yield curr;
  }
}

for (let n of fibonacci()) {
  console.log(n);
  // truncate the sequence at 1000
  if (n >= 1000) {
    break;
  }
}

互換性表:http://kangax.github.io/es5-compat-table/es6/#For..ofループ

Spec:http://wiki.ecmascript.org/doku.php?id=harmony:iterators

}

101

Opera、Safari、Firefox、Chromeは現在、多くの一般的なループを最適化するための一連の拡張Arrayメソッドを共有しています。

あなたはそれらのすべてを必要としないかもしれませんが、それらは非常に有用であるか、またはすべてのブラウザがそれらをサポートするならばそうなるでしょう。

Mozilla Labsは、彼らが WebKit 両方が使用するアルゴリズムを公開しましたので、あなたがそれらを自分で追加することができます。

filter は、何らかの条件またはテストを満たす項目の配列を返します。

every すべての配列メンバがテストにパスした場合はtrueを返します。

some がテストに合格した場合はtrueを返します。

forEach は各配列メンバーに対して関数を実行し、何も返しません。

map はforEachに似ていますが、各要素の演算結果の配列を返します。

これらのメソッドはすべて、最初の引数に関数を取り、オプションの2番目の引数を持ちます。これは、関数をループ処理するときに配列メンバにスコープを設定するオブジェクトです。

必要になるまで無視してください。

indexOf および lastIndexOf 引数と正確に一致する最初または最後の要素の適切な位置を見つけます。

(function(){
    var p, ap= Array.prototype, p2={
        filter: function(fun, scope){
            var L= this.length, A= [], i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        val= this[i];
                        if(fun.call(scope, val, i, this)){
                            A[A.length]= val;
                        }
                    }
                    ++i;
                }
            }
            return A;
        },
        every: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && !fun.call(scope, this[i], i, this))
                        return false;
                    ++i;
                }
                return true;
            }
            return null;
        },
        forEach: function(fun, scope){
            var L= this.length, i= 0;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
            }
            return this;
        },
        indexOf: function(what, i){
            i= i || 0;
            var L= this.length;
            while(i< L){
                if(this[i]=== what)
                    return i;
                ++i;
            }
            return -1;
        },
        lastIndexOf: function(what, i){
            var L= this.length;
            i= i || L-1;
            if(isNaN(i) || i>= L)
                i= L-1;
            else
                if(i< 0) i += L;
            while(i> -1){
                if(this[i]=== what)
                    return i;
                --i;
            }
            return -1;
        },
        map: function(fun, scope){
            var L= this.length, A= Array(this.length), i= 0, val;
            if(typeof fun== 'function'){
                while(i< L){
                    if(i in this){
                        A[i]= fun.call(scope, this[i], i, this);
                    }
                    ++i;
                }
                return A;
            }
        },
        some: function(fun, scope){
            var i= 0, L= this.length;
            if(typeof fun== 'function'){
                while(i<L){
                    if(i in this && fun.call(scope, this[i], i, this))
                        return true;
                    ++i;
                }
                return false;
            }
        }
    }
    for(p in p2){
        if(!ap[p])
            ap[p]= p2[p];
    }
    return true;
})();
84
kennebec

Whileループを使う...

var i=0, item, items = ['one','two','three'];
while(item = items[i++]){
    console.log(item);
}

ログ:「1」、「2」、「3」

逆の順序では、さらに効率的なループ

var items = ['one','two','three'], i = items.length;
while(i--){
    console.log(items[i]);
}

ログ: 'three'、 'two'、 'one'

あるいは古典的なforループ

var items = ['one','two','three']
for(var i=0, l = items.length; i < l; i++){
    console.log(items[i]);
}

ログ:「1」、「2」、「3」

参照: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/

62
Timo Huovinen

イントロ

大学時代から、Java、JavaScript、Pascal、 _ abap _ 、PHP、Progress 4GL、C/C++、そして今では考えられない他のいくつかの言語でプログラムしました。

それらはすべて独自の言語上の特異点を持っていますが、これらの各言語は同じ基本概念の多くを共有しています。このような概念には、プロシージャ/関数、IFステートメント、FORループ、およびWHILEループが含まれます。


伝統的なfor-ループ

従来のforループには、3つの要素があります。

  1. 初期化: lookブロックが最初に実行される前に実行
  2. 条件: ループブロックが実行される前に毎回条件をチェックし、falseの場合はループを終了します。
  3. 後付け: ループブロックが実行された後に毎回実行される

これら3つのコンポーネントは;シンボルによって互いに分離されています。これら3つのコンポーネントのそれぞれの内容はオプションです。つまり、以下は可能な限り最小限のforループです。

for (;;) {
    // Do stuff
}

もちろん、実行を停止させるには、そのfor-ループ内のどこかにif(condition === true) { break; }またはif(condition === true) { return; }を含める必要があります。

ただし、通常、初期化はインデックスを宣言するために使用され、条件はそのインデックスを最小値または最大値と比較するために使用され、後置はインデックスを増分するために使用されます。

for (var i = 0, length = 10; i < length; i++) {
    console.log(i);
}

伝統的なforループを使って配列をループ処理する

配列をループ処理する従来の方法は、次のとおりです。

for (var i = 0, length = myArray.length; i < length; i++) {
    console.log(myArray[i]);
}

あるいは、逆方向にループしたい場合は、次のようにします。

for (var i = myArray.length - 1; i > -1; i--) {
    console.log(myArray[i]);
}

ただし、たとえば次のように、さまざまなバリエーションが考えられます。

for (var key = 0, value = myArray[key], length = myArray.length; key < length; value = myArray[++key]) {
    console.log(value);
}

...またはこれ….

var i = 0, length = myArray.length;
for (; i < length;) {
    console.log(myArray[i]);
    i++;
}

...またはこれ:

var key = 0, value;
for (; value = myArray[key++];){
    console.log(value);
}

どちらが最もうまく機能するかは、主に個人的な好みと、実装している特定のユースケースの両方の問題です。

これらのバリエーションは、非常に古いものも含め、すべてのブラウザでサポートされています。


whileループ

forループの代替手段の1つはwhileループです。配列をループ処理するには、これを実行できます。

var key = 0;
while(value = myArray[key++]){
    console.log(value);
}

forループは、従来のwhileループと同様に、最も古いブラウザでもサポートされています。

また、whileループはすべてforループとして書き換えることができます。たとえば、上記のwhileループは、このfor-ループとまったく同じように動作します。

for(var key = 0; value = myArray[key++];){
    console.log(value);
}

For...infor...of

JavaScriptでは、これを行うこともできます。

for (i in myArray) {
    console.log(myArray[i]);
}

ただし、これはすべての場合において従来のforループと同じ動作をするわけではないため、慎重に使用する必要があります。また、考慮する必要がある可能性のある副作用があります。を参照してください。配列反復で "for ... in"を使用するのはなぜ悪い考えですか。詳細については。

for...in の代わりに、 for...of もあります。次の例は、for...ofループとfor...inループの違いを示しています。

var myArray = [3, 5, 7];
myArray.foo = "hello";

for (var i in myArray) {
  console.log(i); // logs 0, 1, 2, "foo"
}

for (var i of myArray) {
  console.log(i); // logs 3, 5, 7
}

さらに、どのバージョンのInternet Explorerもfor...ofをサポートしていない( Edge 12+ do)こと、およびfor...inには少なくともInternet Explorer 10が必要であることを考慮する必要があります。


Array.prototype.forEach()

for- loopの代わりに、 Array.prototype.forEach() を使用します。これは、次の構文を使用します。

myArray.forEach(function(value, key, myArray) {
    console.log(value);
});

Array.prototype.forEach()は、最近のすべてのブラウザ、およびInternet Explorer 9以降でサポートされています。


図書館

最後に、多くのユーティリティライブラリにも独自のforeachのバリエーションがあります。私の知る限り、3つの最も人気のあるものはこれらです:

jQuery.each() jQuery

$.each(myArray, function(key, value) {
    console.log(value);
});

_.each() Underscore.js

_.each(myArray, function(value, key, myArray) {
    console.log(value);
});

_.forEach() Lodash.js

_.forEach(myArray, function(value, key) {
    console.log(value);
});
52
John Slegers

速いループを書くための簡潔な方法が欲しいなら、あなたは逆に繰り返すことができます:

for (var i=myArray.length;i--;){
  var item=myArray[i];
}

これには、入力する文字数が少なくても、長さをキャッシュするという利点があります(for (var i=0, len=myArray.length; i<len; ++i)に似ていて、for (var i=0; i<myArray.length; ++i)とは異なります)。

繰り返しの間にDOMから項目を削除することを計画している場合、 live NodeList を繰り返し処理する場合など、逆方向に繰り返し処理する必要がある場合もあります。

36
Phrogz

JavaScriptで 関数型プログラミングの方法 で配列をループ処理するユースケースもあります。

1.配列をループするだけ

const myArray = [{x:100}, {x:200}, {x:300}];

myArray.forEach((element, index, array) => {
    console.log(element.x); // 100, 200, 300
    console.log(index); // 0, 1, 2
    console.log(array); // same myArray object 3 times
});

注意:Array.prototype.forEach()は厳密には機能的な方法ではありません。入力パラメータとして使用する関数は値を返すことを想定していないため、純粋な関数と見なすことはできません。

2.配列内のいずれかの要素がテストにパスしたかどうかを確認します

const people = [
    {name: 'John', age: 23}, 
    {name: 'Andrew', age: 3}, 
    {name: 'Peter', age: 8}, 
    {name: 'Hanna', age: 14}, 
    {name: 'Adam', age: 37}];

const anyAdult = people.some(person => person.age >= 18);
console.log(anyAdult); // true

3.新しい配列に変換する

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => element.x);
console.log(newArray); // [100, 200, 300]

注:map()メソッドは、呼び出し元の配列内のすべての要素に対して提供されている関数を呼び出した結果を使用して、新しい配列を作成します。

4.特定の物件を集計し、その平均を計算する

const myArray = [{x:100}, {x:200}, {x:300}];

const sum = myArray.map(element => element.x).reduce((a, b) => a + b, 0);
console.log(sum); // 600 = 0 + 100 + 200 + 300

const average = sum / myArray.length;
console.log(average); // 200

5.元のものに基づいて、それを変更せずに新しい配列を作成します。

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray= myArray.map(element => {
    return {
        ...element,
        x: element.x * 2
    };
});

console.log(myArray); // [100, 200, 300]
console.log(newArray); // [200, 400, 600]

6.各カテゴリーの数を数える

const people = [
    {name: 'John', group: 'A'}, 
    {name: 'Andrew', group: 'C'}, 
    {name: 'Peter', group: 'A'}, 
    {name: 'James', group: 'B'}, 
    {name: 'Hanna', group: 'A'}, 
    {name: 'Adam', group: 'B'}];

const groupInfo = people.reduce((groups, person) => {
    const {A = 0, B = 0, C = 0} = groups;
    if (person.group === 'A') {
        return {...groups, A: A + 1};
    } else if (person.group === 'B') {
        return {...groups, B: B + 1};
    } else {
        return {...groups, C: C + 1};
    }
}, {});

console.log(groupInfo); // {A: 3, C: 1, B: 2}

7.特定の基準に基づいて配列のサブセットを取得する

const myArray = [{x:100}, {x:200}, {x:300}];

const newArray = myArray.filter(element => element.x > 250);
console.log(newArray); // [{x:300}] 

注:filter()メソッドは、提供された関数によって実装されたテストに合格したすべての要素を含む新しい配列を作成します。

8.配列を並べ替える

const people = [
  { name: "John", age: 21 },
  { name: "Peter", age: 31 },
  { name: "Andrew", age: 29 },
  { name: "Thomas", age: 25 }
];

let sortByAge = people.sort(function (p1, p2) {
  return p1.age - p2.age;
});

console.log(sortByAge);

enter image description here

9.配列内の要素を探す

const people = [ {name: "john", age:23},
                {name: "john", age:43},
                {name: "jim", age:101},
                {name: "bob", age:67} ];

const john = people.find(person => person.name === 'john');
console.log(john);

enter image description here

Array.prototype.find()メソッドは、提供されたテスト関数を満たす配列の最初の要素の値を返します。

参考文献

28
Yuci

JavaScriptで配列をループするにはさまざまな方法があります。 

総称ループ:

var i;
for (i = 0; i < substr.length; ++i) {
    // Do something with `substr[i]`
}

ES5のforEach:

substr.forEach(function(item) {
    // Do something with `item`
});

jQuery.each:

jQuery.each(substr, function(index, item) {
    // Do something with `item` (or `this` is also `item` if you like)
});

詳細な情報は this をご覧ください。また、 MDN JavaScriptで配列をループしてjQueryチェックを使用する それぞれのjQuery を確認することもできます。

26
RizN81

ループ内に暗黙のスコープがほとんどなく、余分な変数を削除する場合は、これを実行する方法があります。

var i = 0,
     item;

// note this is weak to sparse arrays or falsey values
for ( ; item = myStringArray[i++] ; ){ 
    item; // This is the string at the index.
}

あるいは、本当にIDを取得して、本当に古典的なforループを作りたいのなら:

var i = 0,
    len = myStringArray.length; // cache the length

for ( ; i < len ; i++ ){
    myStringArray[i]; // Don't use this if you plan on changing the length of the array
}

最近のブラウザはすべて、反復子メソッドforEachmapreducefilter、および Arrayプロトタイプ 上の他のメソッドのホストをサポートしています。 

26
Gabriel

underscore.js ライブラリを利用することを強くお勧めします。それはあなたが配列/コレクションを反復処理するために使用できるさまざまな関数を提供します。

例えば:

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...
25
Andrew Thomson

配列ループ

for(var i = 0; i < things.length; i++){
    var thing = things[i];
    console.log(thing);
}

オブジェクトループ

for(var prop in obj){
    var propValue = obj[prop];
    console.log(propValue);
}
24
bzim

はい、JavaScriptでもループを使用して同じことを実行できますが、JavaScripで配列をループ処理する多くの方法があります。この配列を下に配置して、ループ処理を実行するとします。

var arr = [1, 2, 3, 4, 5];

これらは解決策です:

1)forループ

Forループは、JavaScriptで配列をループ処理する一般的な方法ですが、大規模な配列の最速の解決策とは見なされていません。

for (var i=0, l=arr.length; i<l; i++) { 
  console.log(arr[i]);
}

2)whileループ

Whileループは長い配列をループ処理する最も速い方法と考えられていますが、通常JavaScriptではあまり使用されていません。

let i=0;

while (arr.length>i) {
    console.log(arr[i]);
    i++;
}

3) の間に行う
以下と同じように構文を変えながら、同じことをしながら行います。

let i=0;
do {
  console.log(arr[i]);
  i++;
}
while (arr.length>i);

これらは、JavaScriptループを実行するための主な方法ですが、それを実行する方法は他にもいくつかあります。

また、JavaScriptでオブジェクトをループするためにfor inループを使用します。

JavaScriptのArrayのmap()filter()reduce()などの関数もご覧ください。彼らはwhileforを使うよりはるかに速くそしてより良いことをするかもしれません。

JavaScriptの配列に対する非同期関数についてもっと学びたいなら、これは良い記事です。

最近では関数型プログラミングが開発の世界でかなりのスプラッシュをしています。そして、正当な理由のために:機能的な技法は、一目でわかりやすく理解しやすい宣言的なコードを書くのに役立ちます。

関数型プログラミングの礎石の1つは、リストとリスト操作の特別な使用法です。そしてそれらのことは、まさにがそうであるように聞こえるものです:ものの配列とあなたがそれらにするものしかし、機能的な考え方はそれらをあなたとは少し異なって扱います期待するかもしれません。

この記事では、「big 3」リスト操作(map、filter、およびreduce)を呼び出したいものについて詳しく説明します。これらの3つの関数を頭で囲むことは、きれいな機能コードを書くことができるようにするための重要なステップであり、関数型およびリアクティブ型プログラミングの強力な技法への扉を開きます。

これはまた、forループを二度と書く必要がなくなることを意味します。

もっと読む>> ここ

22
Alireza

JQueryライブラリを使用している場合は、 http://api.jquery.com/jQuery.each/ の使用を検討してください。

ドキュメントから:

jQuery.each( collection, callback(indexInArray, valueOfElement) ) 

戻り値: Object

説明: オブジェクトと配列の両方をシームレスに反復するために使用できる一般的な反復子関数。 lengthプロパティを持つ配列や配列のようなオブジェクト(関数のargumentsオブジェクトなど)は、0からlength-1までの数値インデックスで繰り返されます。他のオブジェクトはそれらの指定されたプロパティを通して反復されます。

$.each()関数は$(selector).each()と同じではありません。これはjQueryオブジェクトを排他的に反復するために使用されるです。 $.each() 関数は、マップ(JavaScriptオブジェクト)であれ配列であれ、任意のコレクションを反復処理するために使用できます。配列の場合、コールバックには時間ごとに配列インデックスと対応する配列値が渡されます。 (thisキーワードでも値にアクセスできますが、単純な文字列または数値であっても、Javascriptは常にthis値をObjectとしてラップします)。 引数、反復されたオブジェクト.

19
justingordon

もし誰かが配列の繰り返しに利用可能な複数のメカニズムのパフォーマンス面に興味があるなら、私は以下のJSPerfテストを用意しました:

https://jsperf.com/fastest-array-iterator

Performamce results

結果 :

伝統的なfor()イテレータは、特にarray length cachedと一緒に使用すると、はるかに速い方法です。

let arr = [1,2,3,4,5];

for(let i=0, size=arr.length; i<size; i++){
    // do something
}

Array.prototype.forEach()メソッドとArray.prototype.map()メソッドは、おそらく関数呼び出しのオーバーヘッドの結果として、最も遅い近似です。 

18
colxi

私はまだこのバリエーションを見ていませんでした。

配列を考えます:

var someArray = ["some", "example", "array"];

Lengthプロパティにアクセスしなくても、ループすることができます。

for (var i=0, item; item=someArray[i]; i++) {
  // item is "some", then "example", then "array"
  // i is the index of item in the array
  alert("someArray[" + i + "]: " + item);
}

それを実証しているこのJsFiddleを見てください: http://jsfiddle.net/prvzk/ /

これはnot sparseである配列に対してのみ機能します。配列の各インデックスに実際に値があることを意味します。しかし、実際にはJavascriptでスパース配列を使用することはほとんどありません。そのような場合は、通常、オブジェクトをマップ/ハッシュテーブルとして使用するほうがはるかに簡単です。疎な配列があり、0 .. length-1をループしたい場合は、for(var i = 0; i <someArray.length; ++ i)の構文が必要ですが、それでもifの内側にifが必要です。現在のインデックスの要素が実際に定義されているかどうかを確認するためのループ。

また、CMSが以下のコメントで述べているように、あなたはこれを偽の値を含まない配列でのみ使用することができます。例の文字列の配列は機能しますが、空の文字列、または0やNaNなどの数値がある場合、ループは途中で中断します。繰り返しますが、これは私にとって問題になることはほとんどありませんが、使用する前にこのループを考慮する必要があることを念頭に置いておく必要があります。

このループについて私が好きなものは:

  • 書くのは短い 
  • Lengthプロパティにアクセスする必要はありません(キャッシュはもちろんのこと) 
  • アクセスする項目は、選択した名前の下のループ本体内に自動的に定義されます。
  • List/stacksのような配列を使うために非常に自然にarray.Pushとarray.spliceを組み合わせます

これが機能するのは、配列の仕様上、インデックスから配列の長さを超えてアイテムを読み込むと、undefinedが返されることを強制するためです。そのような場所に書き込むと、実際に長さが更新されます。

私にとっては、この構文は私が愛するJava 5の構文を最もよくエミュレートしています。

for (String item : someArray) {
}

...ループ内の現在のインデックスについても知るという追加の利点があります。

16
Stijn de Witt

最もエレガントで素早い方法

var arr = [1, 2, 3, 1023, 1024];
for (var value; value = arr.pop();) {
    value + 1
}

http://jsperf.com/native-loop-performance/8


編集しました(私が間違っていたので)


100000項目の配列をループ処理する方法を比較し、毎回新しい値で最小限の操作を実行します。

準備:

<script src="//code.jquery.com/jquery-2.1.0.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.6.0/underscore-min.js"></script>
<script>
    Benchmark.prototype.setup = function() {
        // Fake function with minimal action on the value
        var tmp = 0;
        var process = function(value) {
            tmp = value; // Hold a reference to the variable (prevent engine optimisation?)
        };

        // Declare the test Array
        var arr = [];
        for (var i = 0; i < 100000; i++)
            arr[i] = i;
    };
</script>

テスト:

<a href="http://jsperf.com/native-loop-performance/16" 
   title="http://jsperf.com/native-loop-performance/16"
><img src="http://i.imgur.com/YTrO68E.png" title="Hosted by imgur.com" /></a>
14
molokoloco

JavaScriptでそれをするには2つの方法があります。最初の2つの例はJavaScriptのサンプルです。 3つ目はJavaScriptライブラリを利用する、つまりjQueryが.each()関数を利用することです。

var myStringArray = ["hello", "World"];
for(var i in myStringArray) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
for (var i=0; i < myStringArray.length; i++) {
  alert(myStringArray[i]);
}

var myStringArray = ["hello", "World"];
$.each(myStringArray, function(index, value){
  alert(value);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

14
Shubham Khatri

プロトタイプのものを含まずに、独自のオブジェクトプロパティのみを反復処理する方法があります。

for (var i in array) if (array.hasOwnProperty(i)) {
    // do something with array[i]
}

しかし、それはまだカスタム定義のプロパティに対して繰り返されます。

JavaScriptでは、任意のカスタムプロパティを配列を含む任意のオブジェクトに割り当てることができます。

スパース配列を反復処理したい場合は、for (var i = 0; i < array.length; i++) if (i in array)またはarray.forEaches5shimを使用する必要があります。

14
kirilloid

JavaScriptでは、配列をループするための非常に多くの解決策があります。

以下のコードは人気のあるものです。

/** Declare inputs */
const items = ['Hello', 'World']

/** Solution 1. Simple for */
console.log('solution 1. simple for')

for (let i = 0; i < items.length; i++) {
  console.log(items[i])
}

console.log()
console.log()

/** Solution 2. Simple while */
console.log('solution 2. simple while')

let i = 0
while (i < items.length) {
  console.log(items[i++])
}

console.log()
console.log()

/** Solution 3. forEach*/
console.log('solution 3. forEach')

items.forEach(item => {
  console.log(item)
})

console.log()
console.log()

/** Solution 4. for-of*/
console.log('solution 4. for-of')

for (const item of items) {
  console.log(item)
}

console.log()
console.log()

10

最適化されたアプローチは、配列の長さをキャッシュし、単一のvarキーワードですべての変数を初期化する単一のvarパターンを使用することです。

var i, max, myStringArray = ["Hello","World"];
for (i = 0, max = myStringArray.length; i < max; i++) {
    alert(myStringArray[i]);
   //Do something
}

繰り返しの順序が逆ループを試すよりも重要でない場合は、オーバーヘッド条件のテストが減り、デクリメントが1つのステートメントになるため、最も速くなります。

var i,myStringArray = ["item1","item2"];
for (i =  myStringArray.length; i--) {
    alert(myStringArray[i]);
}

whileループを使うのがより良いか、よりきれいです:

var myStringArray = ["item1","item2"],i = myStringArray.length;
while(i--) {
   // do something with fruits[i]
}
10
Zaheer Ahmed

短い答え:はい。あなたはこれを行うことができます:

var myArray = ["element1", "element2", "element3", "element4"];

for (i = 0; i < myArray.length; i++) {
  console.log(myArray[i]);
}

ブラウザのコンソールでは、 "element1"、 "element2"などが印刷されているのがわかります。

9
Juanjo Salvador

私の考えでは、Array.forEach関数を使用するのが最善の方法です。あなたが私を利用可能にするために私がMDNからpolyfillを得ることを提案することをそれを使用することができないならば、それは確かにJavaScriptで配列を反復する最も安全な方法です。

https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach

他の人が示唆しているように、これはほとんど常にあなたが望むものです:

var numbers = [1,11,22,33,44,55,66,77,88,99,111];
var sum = 0;
numbers.forEach(function(n){
  sum += n;
});

これにより、配列の処理の範囲内で必要なものはすべてその範囲内に収まり、オブジェクトのプロパティや他のメンバではなく、配列の値のみを処理することになります。 

ループに通常のCスタイルを使用すると、ほとんどの場合はうまくいきますが、ループ内のすべてのものがそのスコープとプログラムの他の部分とを共有し、{}は新しいスコープを作成しません。 

それゆえ:

var sum = 0;
var numbers = [1,11,22,33,44,55,66,77,88,99,111];

for(var i = 0; i<numbers.length; ++i){ 
  sum += numbers[i];
}

alert(i);

"11"が出力されます - これはあなたが望むものであるかもしれないしそうでないかもしれません。 

実用的なjsFiddleの例: https://jsfiddle.net/workingClassHacker/pxpv2dh5/7/

9
Espen

たとえば、私はFirefoxのコンソールで使用しました:

[].forEach.call(document.getElementsByTagName('pre'), function(e){ 
   console.log(e);
})
8
victorq10
var x = [4, 5, 6];
for (i = 0, j = x[i]; i < x.length; j = x[++i]) {
    console.log(i,j);
}

もっときれい...

8
staticd

あなたがjQueryを使いたいのであれば、それはそのドキュメンテーションの中にいい例を持っています:

 $.each([ 52, 97 ], function( index, value ) {
      alert( index + ": " + value );
 });
8
jj_

100%同一ではありませんが、似ています。

   var myStringArray = ['Hello', 'World']; // array uses [] not {}
    for (var i in myStringArray) {
        console.log(i + ' -> ' + myStringArray[i]); // i is the index/key, not the item
    }

7
Muhammad Alvin

単純な1行ソリューション

arr = ["table", "chair"];

// solution
arr.map((e) => {
  console.log(e);
  return e;
});

7
BILAL AHMAD

確かにそれは非効率的で多くの人がそれを軽蔑するが、それは言及されたものに最も近いものの1つである:

var myStringArray = ["Hello","World"];
myStringArray.forEach(function(f){
    // Do something
})
6
Daniel K.

forEachを除くすべての亜種を lodash で列挙したようです。

_.forEach([1, 2], (value) => {
  console.log(value);
});
5
Andrew

まあ、これはどうですか:

for (var key in myStringArray) {
    console.log(myStringArray[key]);
}
5
Sambhav Sharma
var myStringArray = ["hello", "World"];
myStringArray.forEach(function(val, index){
   console.log(val, index);
})
5
Amit Jamwal

シーケンシャルなforループを使うほうが良いです:

for (var i = 0; i < myStringArray.length; i++) {
    // Do something
}
4
user6139250

概要:

配列を反復処理するときは、次の目標のいずれかを達成したいことがよくあります。

  1. 元の配列を変更せずに新しい配列を作成します。use map()
  2. すべての配列要素に対して/を指定してアクションを実行し、配列を変更する可能性があります。for..offorEach()、または通常のforループを使用します。

例:

const arr1 = [1, 2, 3];

const arr2 = arr1.map(el => el * 2);

// with map we create a new arr2, arr1 is left untouched
console.log(arr2, arr1);


// regular for loop
for (let i = 0; i < arr1.length; i++) {
  console.log(arr1[i]);
}

console.log('\n');

// for of loop
for (let el of arr1) {
  console.log(el);

}

console.log('\n');


// forEach()
arr1.forEach(el => {
  console.log(el)
})

どれを使う?

ほとんどの場合、それほど重要ではありません。ただし、Edgeのケースでは、1つの種類の反復がニーズに適している可能性があります。

  1. 配列を操作したいが古い配列をそのままにしておきたい場合(例えば関数型プログラミング)、反復のためにmap()を使用するのが最善です。新しい配列を返す必要がない場合はmap()を使用しないでください。 map()は、すべてのループメソッドの中で最もパフォーマンスが遅くなります。
  2. パフォーマンスが重要な役割を果たすとき、非常に多くの回数を繰り返す必要があるときは、通常のforループを使用します。

for(let i=0; i < arr.length; i++) {}

それは最も「低レベル」の形式の反復であるため、(JSエンジンの違いにより異なる可能性があります)最高のパフォーマンスを持つことがよくあります。 

4
var obj = ["one","two","three"];

for(x in obj){
    console.log(obj[x]);
}
3
Dan Chill

再帰的に配列をループする 

const data = ['one', 'two', 'three']

const loop = (items, index=0) => {
  if (items.length === index) {
    return;
  }
  console.log(items[index], index)
  loop(items, index+=1)
}

loop(data)
2
John Ottenlips

arr.forEach(...)を使用できます:

var arr = ["Apple", "banana", "cherry", "mango"];
arr.forEach((item, index)=>{
   //Some code...
});

またはarr.map(...)

var arr = ["Apple", "banana", "cherry", "mango"];
arr.map((item, index)=>{
   //Some code...
});

または、前述のjqueryまたはforループの方法。

2
Raphael Spoerri

var array = ['hai', 'hello', 'how', 'are', 'you']
$(document).ready(function () {
  $('#clickButton').click(function () {
    for (var i = 0; i < array.length; i++) {
      alert(array[i])
    }
  })
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<input id="clickButton" value="click Me" type="button"/>
<div id="show"></div>

0
Shijo Rs