javascript - 連想配列 - jquery 配列 ループ




JavaScriptで配列をループする (20)

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

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

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


for(myStringArrayのvar s)

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

他のほとんどの答えは正しいですが、 ECMA Script 6 2015が反復を行うための新しいメカニズム、 for..ofループをもたらしているとは言及していません。

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

現在、Firefox 13+、Chrome 37+で動作し、他のブラウザとはネイティブに動作しません(下記のブラウザ互換性を参照)。 幸運なことに、今日の次世代機能を使用できるJSコンパイラ( Babelなど)があります。

また、ノード上で動作します(私はバージョン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ループ

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

}


最もエレガントで速い方法

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>

JavaScriptではfor-inループで配列をループすることはお勧めできませんが、forループを使用する方が良いでしょう:

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

それは最適化されています(配列の長さを "キャッシュ")。 詳細を知りたい場合は、 私の記事を読んでください


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を見てみるか、JavaScriptで配列をループして&jQuery check jQuery.each()使ってfor...inをチェックすることもできます。


Opera、Safari、Firefox、Chromeはすべて、多くの共通ループを最適化するための拡張されたArrayメソッドを共有しています。

それらのすべてが必要なわけではありませんが、非常に便利な場合もあれば、すべてのブラウザでサポートされている場合もあります。

Mozilla Labsは、 WebKitWebKit両方のアルゴリズムを公開していますので、自分で追加することができます。

フィルターは、いくつかの条件またはテストを満たす項目の配列を返します。

everyはすべての配列メンバがテストに合格するとtrueを返します。

テストに合格すると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;
})();

whileループを使用する...

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

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

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

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

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

リファレンス: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/ : http://www.sitepoint.com/google-closure-how-not-to-write-javascript/


PythonHaskellような他の言語でも利用できる関数型プログラミングテクニックであるmapを使うことができます。

[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取得しないことを除いて。


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


あなたが高速なループを書くための簡潔な方法を望んでいれば、逆に反復することができます:

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から項目を削除する予定のライブNodeListを反復処理する場合など、逆に反復する必要がある場合もあります。


あなたのループに暗黙のスコープがほとんどなく、余分な変数をなくす方法があります。

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ループが必要な場合は、次のように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プロトタイプの他のメソッドのホストをサポートしています。


はい、あなたはループを使って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)
以下のようないくつかの構文の違いで同じことしながらDoをしながら:

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

これらはjavascriptループを実行する主な方法ですが、これを行う方法はいくつもあります。

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

また見てmap()filter()reduce()JavaScriptで配列上などの機能。彼らは使用するよりも、物事はより速く、よりよく行うことができますwhilefor

これは、JavaScriptの配列に対する非同期関数の詳細を知りたければ、良い記事です。

近年、機能プログラミングは、開発の世界でかなりの飛躍を遂げています。正当な理由があります:機能的なテクニックは、一目で分かりやすいリファクタリングとテストをより多くの宣言型コードで記述するのに役立ちます。

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

この記事では、map、filter、およびreduceの3つのリスト操作を「ビッグ3」リスト操作と呼んでいます。これらの3つの機能の周りにあなたの頭を包むことは、クリーンな機能コードを書くことができるようになるための重要なステップであり、機能的で反応的なプログラミングの非常に強力な技術への扉を開きます。

また、forループを再度書く必要がないことを意味します。

もっと読む>> here


はい。ただし、実装にECMAScript 2015で導入された機能(「ハーモニー」リリース)が含まれている場合に限ります。

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

// 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仕様の以前のエディション(Internet Explorerのバージョンが9より前のバージョンなど)に準拠していると想定できる場合は、ループの代わりにforEach iteratorメソッドを使用できます。 その場合、配列の各項目に呼び出される関数を渡します。

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

しかし、それがあまりにも多すぎて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) {

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


最適化された方法は、配列の長さをキャッシュし、単一の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]
}

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

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

私はこのバリエーションをまだ見ていない、私は個人的には最高の:

与えられた配列:

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/ ://jsfiddle.net/prvzk/http://jsfiddle.net/prvzk/

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

また、以下のコメントでCMSが言及しているように、これは誤った値を含まない配列に対してのみ使用できます。この例の文字列の配列は機能しますが、空の文字列、または0やNaNなどの数字がある場合は、ループが途中で途切れることになります。ここでもまた実際にはこれは私にとってはほとんど問題ではありませんが、使用する前にこれを考えるループとなることを覚えておいてください...それは一部の人にとっては不適格かもしれません:)

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

  • それは書くのが簡単です
  • lengthプロパティにアクセスする必要はありません。
  • アクセスする項目は、選択した名前でループ本体内で自動的に定義されます。
  • リスト/スタックのような配列を使うために、array.pushとarray.spliceと非常に自然に結合する

これがうまくいく理由は、配列の指定は、ある項目をインデックス> =配列の長さから読み取ると、undefinedを返すことを要求しているためです。そのような場所に書き込むと、実際に長さが更新されます。

私の場合、この構文は、私が愛しているJava 5の構文を最もよく模倣しています。

for (String item : someArray) {
}

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


誰かがArrayの反復で利用できる複数のメカニズムのパフォーマンス面に興味があるなら、私は次のJSPerfテストを準備しました:

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

結果 :

従来のfor()イテレーターは、はるかに速い方法です。特に、キャッシュされ配列の長さで使用すると便利です。

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()方法は、おそらくの結果として、最も遅い近似である関数呼び出しのオーバーヘッド


順次forループを使用する:

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

@zipcodemanはfor...in文の使用を提案しますが、 for...in for-in配列for-in反復することは避けるべきです。その文はオブジェクトのプロパティを列挙するためのものです。

配列のようなオブジェクトには使用しないでください。

  • 反復の順序は保証されていませんが、配列インデックスは数値順にアクセスされません。
  • 継承されたプロパティも列挙されます。

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

例えば:

Array.prototype.foo = "foo!";
var array = ['a', 'b', 'c'];

for (var i in array) {
  alert(array[i]);
}

上記のコードでは、 "a"、 "b"、 "c"、 "foo!"という警告が表示されます。

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

前に述べたようなfor-in文は、オブジェクトのプロパティを列挙するためのものです。例えば、次のようになります。

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...
    alert("prop: " + prop + " value: " + obj[prop])
  }
}

上記の例では、 hasOwnPropertyメソッドを使用すると、オブジェクトが物理的に持つプロパティだけが継承されたプロパティを持たず、 独自のプロパティのみを列挙できます。

私はあなたに次の記事を読むことをお勧めします:


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

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>


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

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

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

ブラウザコンソールでは、「element1」、「element2」などのようなものが表示されます。


私の意見では、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"が出力されます - あなたが望むかもしれないし、そうでないかもしれない。

作業中の例:https://jsfiddle.net/workingClassHacker/pxpv2dh5/7/ ://jsfiddle.net/workingClassHacker/pxpv2dh5/7/https://jsfiddle.net/workingClassHacker/pxpv2dh5/7/





for-loop