對於JavaScript中的每個數組?


Answers

編輯 :這個答案是絕望的過時。 對於更現代的方法,請查看數組上可用的方法 。 感興趣的方法可能是:

  • 的forEach
  • 地圖
  • 過濾
  • 壓縮
  • 減少
  • 一切
  • 一些

JavaScript迭代一個數組的標準方法是一個for -loop的vanilla:

var length = arr.length,
    element = null;
for (var i = 0; i < length; i++) {
  element = arr[i];
  // Do something with element i.
}

但是,請注意,如果您有一個密集的數組,並且每個索引都被一個元素佔據,那麼這種方法才是有效的。 如果數組很稀疏,那麼你可以用這種方法來解決性能問題,因為你會迭代很多在數組中並不存在的索引。 在這種情況下, for .. in -loop可能是一個更好的主意。 但是 ,您必須使用適當的安全措施以確保只對數組(即數組元素)所需的屬性起作用,因為for..in -loop也將在舊版瀏覽器中枚舉,或者如果額外屬性被定義為enumerable

ECMAScript 5中 ,數組原型上會有forEach方法,但在傳統瀏覽器中不支持。 因此,為了能夠始終如一地使用它,您必須擁有一個支持它的環境(例如,用於服務器端JavaScript的Node.js ),或者使用“Polyfill”。 然而,這個功能的填充是微不足道的,因為它使得代碼更易於閱讀,所以它是一個很好的填充。

Question

如何使用JavaScript循環訪問數組中的所有條目?

我認為這是這樣的:

forEach(instance in theArray)

陣列是我的陣列,但這似乎是不正確的。




Probably the for(i = 0; i < array.length; i++) loop is not the best choice. 為什麼? If you have this:

var array = new Array();
array[1] = "Hello";
array[7] = "World";
array[11] = "!";

The method will call from array[0] to array[2] . First, this will first reference variables you don't even have, second you would not have the variables in the array, and third this will make the code bolder. Look here, it's what I use:

for(var i in array){
    var el = array[i];
    //If you want 'i' to be INT just put parseInt(i)
    //Do something with el
}

And if you want it to be a function, you can do this:

function foreach(array, call){
    for(var i in array){
        call(array[i]);
    }
}

If you want to break, a little more logic:

function foreach(array, call){
    for(var i in array){
        if(call(array[i]) == false){
            break;
        }
    }
}

例:

foreach(array, function(el){
    if(el != "!"){
        console.log(el);
    } else {
        console.log(el+"!!");
    }
});

它返回:

//Hello
//World
//!!!



An easy solution now would be to use the underscore.js library . It's providing many useful tools, such as each and will automatically delegate the job to the native forEach if available.

A CodePen example of how it works is:

var arr = ["elemA", "elemB", "elemC"];
_.each(arr, function(elem, index, ar)
{
...
});

也可以看看

  • Array::forEach .
  • In for_each...in (MDN) it is explained that for each (variable in object) is deprecated as the part of ECMA-357 ( EAX ) standard.
  • for...of (MDN) describes the next way of iterating using for (variable of object) as the part of the Harmony (ECMAScript 6) proposal.



The lambda syntax doesnt usually work in IE 10 or below.

I usually use the

[].forEach.call(function(value,index){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});


If you are a jQuery Fan and already have a jQuery file running, you should reverse the positions of the index and value parameters

$("#ul>li").each(function(**index,value**){
    console.log("value of the looped element" + value);
    console.log("index of the looped element" + index);
});



ECMAScript5 (the version on Javascript) to work with Arrays.

forEach - Iterates through every item in the array and do whatever you need with each item.

['C', 'D', 'E'].forEach(function(element, index) {
  console.log(element + " is the #" + (index+1) + " in musical scale");
});

// Output
// C is the #1 in musical scale
// D is the #2 in musical scale
// E is the #3 in musical scale

In case , more interested on operation on array using some inbuilt feature.

map - It creates a new array with the result of the callback function. This method is good to be used when you need to format the elements of your array.

// Let's upper case the items in the array
['bob', 'joe', 'jen'].map(function(elem) {
  return elem.toUpperCase();
});

// Output: ['BOB', 'JOE', 'JEN']

reduce - As the name says it reduces the array to a single value by calling the given function passing in the currenct element and the result of the previous execution.

[1,2,3,4].reduce(function(previous, current) {
  return previous + current;
});
// Output: 10
// 1st iteration: previous=1, current=2 => result=3
// 2nd iteration: previous=3, current=3 => result=6
// 3rd iteration: previous=6, current=4 => result=10

every - Returns true or false if all the elements in the array pass the test in the callback function.

// Check if everybody has 18 years old of more.
var ages = [30, 43, 18, 5];  
ages.every(function(elem) {  
  return elem >= 18;
});

// Output: false

filter - Very similar to every except that filter return an array with the elements that return true to the given function.

// Finding the even numbers
[1,2,3,4,5,6].filter(function(elem){
  return (elem % 2 == 0)
});

// Output: [2,4,6]

Hope this will be useful.




我知道這是一個舊帖子,已經有很多很好的答案。 為了更完整一些,我想我會使用AngularJS投入另一個。 當然,這只適用於使用Angular的情況,顯然,儘管如此,我仍想說明。

angular.forEach需要2個參數和一個可選的第三個參數。 第一個參數是要迭代的對象(數組),第二個參數是迭代器函數,第三個參數是可選的對像上下文(基本上在循環內部稱為“this”。

There are different ways to use the forEach loop of angular. The simplest and probably most used is

var temp = [1, 2, 3];
angular.forEach(temp, function(item) {
    //item will be each element in the array
    //do something
});

Another way that is useful for copying items from one array to another is

var temp = [1, 2, 3];
var temp2 = [];
angular.forEach(temp, function(item) {
    this.push(item); //"this" refers to the array passed into the optional third parameter so, in this case, temp2.
}, temp2);

Though, you don't have to do that, you can simply do the following and it's equivalent to the previous example:

angular.forEach(temp, function(item) {
    temp2.push(item);
});

Now there are pros and cons of using the angular.forEach function as opposed to the built in vanilla-flavored for loop.

優點

  • Easy readability
  • Easy writability
  • If available, angular.forEach will use the ES5 forEach loop. Now, I will get to efficientcy in the cons section, as the forEach loops are much slower than the for loops. I mention this as a pro because it's nice to be consistent and standardized.

Consider the following 2 nested loops, which do exactly the same thing. Let's say that we have 2 arrays of objects and each object contains an array of results, each of which has a Value property that's a string (or whatever). And let's say we need to iterate over each of the results and if they're equal then perform some action:

angular.forEach(obj1.results, function(result1) {
    angular.forEach(obj2.results, function(result2) {
        if (result1.Value === result2.Value) {
            //do something
        }
    });
});

//exact same with a for loop
for (var i = 0; i < obj1.results.length; i++) {
    for (var j = 0; j < obj2.results.length; j++) {
        if (obj1.results[i].Value === obj2.results[j].Value) {
            //do something
        }
    }
}

Granted this is a very simple hypothetical example, but I've written triple embedded for loops using the second approach and it was very hard to read, and write for that matter.

缺點

  • Efficiency. angular.forEach , and the native forEach , for that matter, are both so much slower than the normal for loop....about 90% slower . So for large data sets, best to stick to the native for loop.
  • No break, continue, or return support. continue is actually supported by " accident ", to continue in an angular.forEach you simple put a return; statement in the function like angular.forEach(array, function(item) { if (someConditionIsTrue) return; }); which will cause it to continue out of the function for that iteration. This is also due to the fact that the native forEach does not support break or continue either.

I'm sure there's various other pros and cons as well, and please feel free to add any that you see fit. I feel that, bottom line, if you need efficiency, stick with just the native for loop for your looping needs. But, if your datasets are smaller and a some efficiency is okay to give up in exchange for readability and writability, then by all means throw an angular.forEach in that bad boy.




如果你想循環一個數組,使用標準的三部分for循環。

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

通過緩存myArray.length或向後迭代,可以獲得一些性能優化。




There isn't any for each loop in native JavaScript . You can either use libraries to get this functionality (I recommend Underscore.js ), use a simple for in loop.

for (var instance in objects) {
   ...
}

However, note that there may be reasons to use an even simpler for loop (see question Why is using “for…in” with array iteration such a bad idea? )

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



There are a few ways to loop through an array in JavaScript, as below:

for - it's the most common one. Full block of code for looping

var languages = ["JAVA", "JavaScript", "C#", "Python"];
var i, len, text;
for (i = 0, len = languages.length, text = ""; i < len; i++) {
    text += languages[i] + "<br>";
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

while - loop while a condition is through. It seems to be the fastest loop

var text = "";
var i = 0;
while (i < 10) {
    text +=  i + ") something<br>";
    i++;
}
document.getElementById("example").innerHTML = text;
<p id="example"></p>

do/while - also loop through a block of code while the condition is true, will run at least one time

var text = ""
var i = 0;
do {
    text += i + ") something <br>";
    i++;
}
while (i < 10);
document.getElementById("example").innerHTML = text;
<p id="example"></p>

Functional loops - forEach , map , filter , also reduce (they loop through the function, but used if you need to do something with your array, etc.

// For example, in this case we loop through the number and double them up using the map function
var numbers = [65, 44, 12, 4];
document.getElementById("example").innerHTML = numbers.map(function(num){return num * 2});
<p id="example"></p>

For more information and examples about functional programming on arrays, look at the blog post Functional programming in JavaScript: map, filter and reduce .




jQuery way using $.map :

var data = [1, 2, 3, 4, 5, 6, 7];

var newData = $.map(data, function(element) {
    if (element % 2 == 0) {
        return element;
    }
});

// newData = [2, 4, 6];



向後循環

我認為這個循環的反面值得在這裡提及:

for (var i = array.length; i--; ) {
     // process array[i]
}

優點:

  • 您不需要聲明臨時len變量,或者在每次迭代時比較array.length ,其中任何一種都可能是一分鐘優化。
  • 以相反的順序從DOM中刪除兄弟姐妹通常更有效 。 (瀏覽器需要減少內部數組中元素的移動。)
  • 如果在循環時修改數組 ,在索引i處或之後(例如,您在array[i]處刪除或插入項目),則前向循環會跳過左移到位置i的項目 ,或者重新處理i該項目右移。 在傳統的for循環中,可以 i更新為指向需要處理的下一個項目 - 1,但簡單地顛倒迭代方向通常是更簡單更優雅的解決方案
  • 同樣,修改或刪除嵌套的 DOM元素時,反向處理可以規避錯誤 。 例如,考慮在處理子節點之前修改父節點的innerHTML。 在達到子節點時,它將從DOM中分離出來,在父節點的innerHTML被寫入時由新創建的子節點替換。
  • 鍵入和閱讀的時間比可用的其他選項 。 雖然它損失forEach()和ES6的for ... of

缺點:

  • 它以相反的順序處理項目。 如果您從結果中創建一個新數組,或者在屏幕上打印某些東西, 那麼輸出結果自然與原始訂單相反
  • 作為第一個孩子反复插入兄弟姐妹以保留其順序效率較低 。 (瀏覽器將不得不正確地轉移事情。)為了有效地創建DOM節點並按順序創建,只需向前循環並按正常方式追加(也可以使用“文檔片段”)。
  • 反向循環讓初級開發人員感到困惑 。 (你可能會認為這是一種優勢,取決於你的前景。)

我應該一直使用它嗎?

有些開發人員默認使用反向循環,除非有充分的理由向前循環。

雖然表現收益通常不顯著,但它有點尖叫:

“只要對列表中的每一項都做到這一點,我就不會關心訂單!”

然而在實踐中,這實際上並不是一個可靠的意向指示,因為它與那些關心訂單的場合沒有區別,並且確實需要反向循環。 因此實際上,需要另一種構造來準確地表達“不關心”意圖,這在大多數語言中都是不可用的,包括ECMAScript,但可以稱為forEachUnordered()

如果順序無關緊要,並且效率是一個問題(在遊戲或動畫引擎的最內層循環中),那麼使用reverse for loop作為您的前往模式也是可以接受的。 請記住,在現有代碼查看循環的反向並不一定意味著該命令不相關!

最好使用forEach()

一般來說,對於清晰度和安全性更高的高層代碼,我建議使用Array::forEach作為默認模式:

  • 閱讀很清楚。
  • 這表明不會在塊內移動(這總是隱藏在long和while循環中的可能的驚喜。)
  • 它為您提供了一個免費的關閉範圍。
  • 它減少了局部變量的洩漏以及與外部變量的(和突變)意外碰撞。

然後,當你看到代碼中的循環反向時,這是一個暗示,它有一個很好的原因(可能是上面描述的原因之一)。 看到一個傳統的循環前進可能表明可能發生變化。

(如果對意圖的討論對你沒有意義,那麼你和你的代碼可以從觀看Crockford關於編程風格和你的大腦的講座中受益。)

它是如何工作的?

for (var i = 0; i < array.length; i++) { ... }   // Forwards

for (var i = array.length; i--; )    { ... }   // Reverse

你會注意到i--是中間子句(我們通常會看到一個比較),最後一個子句是空的(我們通常會看到i++ )。 這意味著我也被用作延續的條件 。 最重要的是,它每次迭代之前執行並檢查。

  • 如何從array.length開始而不爆炸?

    因為i-- 每次迭代之前運行,所以在第一次迭代時,我們將實際訪問array.length - 1的項目,這樣可以避免Array-out-of-bounds undefined項目的任何問題。

  • 為什麼它不會在索引0之前停止迭代?

    當條件i評估為假值(當它產生0)時,循環將停止迭代。

    訣竅是,不像--i ,後面的i--操作符遞減i但在遞減之前產生該值。 你的控制台可以證明這一點

    > var i = 5; [i, i--, i];

    [5, 5, 4]

    所以在最後一次迭代中, 以前是1 ,而i--表達式將其更改為0,但實際上產生1 (truthy),所以條件通過。 在下一次迭代中, i--i更改為-1,但產生0 (falsey),導致執行立即從循環底部退出。

    在傳統的前向循環中, i++++i是可以互換的(正如Douglas Crockford指出的那樣)。 然而,在循環的反面,因為我們的遞減也是我們的條件表達式,所以我們必須堅持使用i--如果我們想處理索引為0的項。

瑣事

有些人喜歡在反向循環中繪製一個小箭頭,並以一個眨眼結束:

for (var i = array.length; i --> 0 ;) {

積分轉到WYL,向我展示反向循環的好處和恐怖。