arrays перебор - Для каждого по массиву в JavaScript?




массива массивы (24)

Как я могу перебирать все записи в массиве с помощью JavaScript?

Я думал, что это что-то вроде этого:

forEach(instance in theArray)

Где theArray - мой массив, но это кажется неправильным.


Answers

Я также хотел бы добавить это как состав обратной петли и ответ выше для тех, кто хотел бы также использовать этот синтаксис.

var foo = [object,object,object];
for (var i = foo.length, item; item = foo[--i];) {
    console.log(item);
}

Плюсы:

Выгода для этого: у вас есть ссылка уже в первом, что не нужно будет объявлять позже с другой строкой. Это удобно при циклическом перемещении по массиву объектов.

Минусы:

Это будет прерываться всякий раз, когда ссылка ложна - false (undefined и т. Д.). Однако это можно использовать как преимущество. Однако, это сделало бы его немного труднее читать. А также в зависимости от браузера он может быть «не» оптимизирован для работы быстрее оригинального.


Я знаю, что это старый пост, и есть много замечательных ответов.Для немного более полноты я решил, что я бы выбрал другой, используя AngularJS . Конечно, это применимо только в том случае, если вы используете Angular, очевидно, тем не менее, я все равно хотел бы выразить это.

angular.forEachпринимает 2 аргумента и необязательный третий аргумент. Первый аргумент - это объект (массив) для итерации, второй аргумент - это функция итератора, а необязательный третий аргумент - это контекст объекта (в основном называемый внутри цикла как «это».

Существуют различные способы использования цикла forEach для углов. Самый простой и, вероятно, наиболее используемый

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

Другой способ, который полезен для копирования элементов из одного массива в другой, - это

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

Хотя вам этого не нужно, вы можете просто сделать следующее, и это эквивалентно предыдущему примеру:

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

Теперь есть плюсы и минусы использования angular.forEachфункции в отличие от встроенной forпетли с ароматом ванили .

Pros

  • Легкая читаемость
  • Легкость записи
  • Если доступно, angular.forEachбудет использоваться цикл ES5 forEach. Теперь я получу эффективность в разделе cons, поскольку петли forEach намного медленнее, чем циклы for. Я упоминаю это как профессионала, потому что приятно быть последовательным и стандартизованным.

Рассмотрим следующие два вложенных цикла, которые делают точно то же самое. Предположим, что у нас есть 2 массива объектов, и каждый объект содержит массив результатов, каждый из которых имеет свойство Value, которое представляет собой строку (или что-то еще). И, допустим, нам нужно перебирать каждый из результатов и, если они равны, выполните некоторые действия:

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

Конечно, это очень простой гипотетический пример, но я написал тройной встроенный для циклов, используя второй подход, и его было очень трудно читать и писать по этому вопросу.

Cons

  • Эффективность. angular.forEach, и нативные forEach, если на то пошло, настолько медленнее, чем нормальный forцикл ... примерно на 90% медленнее . Поэтому для больших наборов данных лучше всего придерживаться собственного forцикла.
  • Без перерыва, продолжения или возврата поддержки. continueна самом деле поддерживается « accident », чтобы продолжить в angular.forEachпростом представлении return;оператора в функции, angular.forEach(array, function(item) { if (someConditionIsTrue) return; });которая заставит его продолжить работу из этой итерации. Это также связано с тем, что нативный forEachне поддерживает перерыв или продолжается.

Я уверен, что есть и другие плюсы и минусы, и, пожалуйста, не стесняйтесь добавлять все, что сочтет нужным. Я чувствую, что в нижней строке, если вам нужна эффективность, придерживайтесь только собственного forцикла для ваших нужд цикла. Но, если ваши наборы данных меньше, и некоторая эффективность в порядке, чтобы отказаться от обмена на удобочитаемость и возможность записи, тогда, во что бы то ни стало, бросить angular.forEachэтого плохого мальчика.


Вероятно, for(i = 0; i < array.length; i++)петля - не лучший выбор. Зачем? Если у вас есть это:

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

Метод вызовет от array[0]до array[2]. Во-первых, это сначала будет ссылаться на переменные, которых у вас даже нет, во-вторых, у вас не будет переменных в массиве, а в-третьих, это сделает код более смелым. Послушайте, это то, что я использую:

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

И если вы хотите, чтобы это была функция, вы можете сделать это:

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

Если вы хотите сломать, немного логичнее:

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
//!!!

Синтаксис лямбда обычно не работает в IE 10 или ниже.

Обычно я использую

[].forEach.call(arrayName,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);
});

Теперь простое решение - использовать библиотеку underscore.js . Он предоставляет множество полезных инструментов, например, eachи автоматически делегирует задание на родной, forEachесли он доступен.

Пример использования CodePen :

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

Смотрите также

  • Array::forEach .
  • В for_each...in (MDN) объясняется, что for each (variable in object)он устарел как часть стандарта ECMA-357 ( EAX ).
  • for...of (MDN) описывает следующий способ повторения использования for (variable of object)в качестве части предложения Harmony (ECMAScript 6).

Если у вас массивный массив, вы должны использовать его iteratorsдля повышения эффективности. Итераторы являются собственностью определенных JavaScript коллекций (как Map, Set, String, Array). Даже, for...ofиспользует iteratorпод капотом.

Итераторы повышают эффективность, позволяя вам потреблять элементы в списке по одному, как если бы они были потоком. Что делает специальный итератор особенным, так это то, как он перемещается по коллекции. Другие циклы должны загружать всю коллекцию спереди, чтобы перебирать ее, тогда как итератору нужно знать только текущую позицию в коллекции.

Вы получаете доступ к текущему элементу, вызывая метод итератора next. Следующий метод вернет valueтекущий элемент и a, booleanчтобы указать, когда вы достигли конца коллекции. Ниже приведен пример создания итератора из массива.

Преобразуйте свой обычный массив в итератор, используя следующий values()метод:

    const myArr = [2,3,4]

let it = myArr.values();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

Вы также можете преобразовать свой обычный массив в итератор, используя Symbol.iteratorследующее:

const myArr = [2,3,4]

let it = myArr[Symbol.iterator]();

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

Вы также можете преобразовать свой обычный arrayобраз iteratorsтак:

let myArr = [8, 10, 12];

function makeIterator(array) {
    var nextIndex = 0;
    
    return {
       next: function() {
           return nextIndex < array.length ?
               {value: array[nextIndex++], done: false} :
               {done: true};
       }
    };
};

var it = makeIterator(myArr);

console.log(it.next().value);   // {value: 8, done: false}
console.log(it.next().value);   // {value: 10, done: false}
console.log(it.next().value);   // {value: 12, done: false}
console.log(it.next().value);   // {value: undefined, done: true}

ПРИМЕЧАНИЕ .

  • Итераторы носят исчерпывающий характер.
  • Объекты не iterableпо умолчанию. Используйте for..inв этом случае, потому что вместо значений он работает с ключами.

Вы можете прочитать iteration protocol here больше .


TL; DR

  • Не используйте for-in если вы не используете его с защитой или, по крайней мере, не знаете, почему он может вас укусить.
  • Ваши лучшие ставки обычно

    • for-of loop (только ES2015 +),
    • Array#forEach ( spec | MDN ) (или его родственники some и т. Д.) (Только ES5 +),
    • простой старомодный цикл,
    • или for-in входа с защитой.

Но есть еще много возможностей для изучения, чтения ...

JavaScript имеет мощную семантику для циклического преобразования массивов и объектов типа массива. Я разделил ответ на две части: варианты для подлинных массивов и варианты для вещей, которые просто похожи на массив, такие как объект arguments , другие объекты с истребителями (ES2015 +), коллекции DOM и т. Д.

Я быстро заметлю, что теперь вы можете использовать опции ES2015, даже на двигателях ES5, путем пересылки ES2015 на ES5. Найдите «ES2015 transpiling» / «ES6 transpiling» для более ...

Хорошо, давайте посмотрим на наши варианты:

Для реальных массивов

У вас есть три варианта в ECMAScript 5 («ES5»), версия, наиболее широко поддерживаемая на данный момент, и еще две добавленные в ECMAScript 2015 («ES2015», «ES6»):

  1. Использовать forEach и связанные с ним (ES5 +)
  2. Используйте простой цикл
  3. Правильно использовать for-in
  4. Использовать for-of (использовать итератор неявно) (ES2015 +)
  5. Использовать итератор явно (ES2015 +)

Подробности:

1. Использовать forEach и связанные с ним

В любой неопределенно современной среде (так, а не в IE8), где у вас есть доступ к функциям Array добавленным ES5 (напрямую или с использованием полиполнений), вы можете использовать forEach ( spec | MDN ):

var a = ["a", "b", "c"];
a.forEach(function(entry) {
    console.log(entry);
});

forEach принимает функцию обратного вызова и, необязательно, значение, используемое как this при вызове этого обратного вызова (не используется выше). Обратный вызов вызывается для каждой записи в массиве, чтобы пропустить несуществующие записи в разреженных массивах. Хотя я использовал только один аргумент выше, обратный вызов вызывается с тремя: значение каждой записи, индекс этой записи и ссылка на массив, который вы повторяете (в случае, если ваша функция еще не имеет его ).

Если вы не поддерживаете устаревшие браузеры, такие как IE8 (которые NetApps показывает на уровне более 4% рынка на момент написания этой статьи в сентябре 2016 года), вы можете с радостью использовать forEach на универсальной веб-странице без прокладки. Если вам нужно поддерживать устаревшие браузеры, легко выполнить операцию shimming / polyfilling forEach (найдите «es5 shim» для нескольких опций).

forEach имеет то преимущество, что вам не нужно объявлять индексирование и переменные значения в области содержимого, поскольку они поставляются в качестве аргументов функции итерации и настолько хорошо ориентированы на эту итерацию.

Если вы беспокоитесь о затратах времени выполнения вызова функции для каждой записи массива, не будьте; blog.niftysnippets.org/2012/02/foreach-and-runtime-cost.html .

Кроме того, forEach - это функция «loop through them all», но ES5 определил несколько других полезных «проработок через функции массива и вещей», в том числе:

  • every (останавливает цикл в первый раз, когда обратный вызов возвращает false или что-то ложное)
  • some (останавливает цикл в первый раз, когда обратный вызов возвращает true или что-то правдоподобное)
  • filter (создает новый массив, включающий элементы, в которых функция фильтра возвращает true и опускает те, где она возвращает false )
  • map (создает новый массив из значений, возвращаемых обратным вызовом)
  • reduce (наращивает значение, повторно вызывая обратный вызов, передавая предыдущие значения, см. спецификацию для деталей, полезно для суммирования содержимого массива и многих других вещей)
  • reduceRight (например, reduce , но работает в нисходящем, а не восходящем порядке)

2. Используйте простой цикл

Иногда старые способы являются лучшими:

var index;
var a = ["a", "b", "c"];
for (index = 0; index < a.length; ++index) {
    console.log(a[index]);
}

Если длина массива не будет меняться во время цикла, и это код, чувствительный к производительности (маловероятно), немного более сложная версия, захватывающая длину спереди, может быть немного быстрее:

var index, len;
var a = ["a", "b", "c"];
for (index = 0, len = a.length; index < len; ++index) {
    console.log(a[index]);
}

И / или считая назад:

var index;
var a = ["a", "b", "c"];
for (index = a.length - 1; index >= 0; --index) {
    console.log(a[index]);
}

Но с современными механизмами JavaScript редко вам нужно выкупить этот последний сок.

В ES2015 и выше вы можете сделать свой индекс и переменные значений локальными for цикла for :

let a = ["a", "b", "c"];
for (let index = 0; index < a.length; ++index) {
    let value = a[index];
}
//console.log(index); // Would cause "ReferenceError: index is not defined"
//console.log(value); // Would cause "ReferenceError: value is not defined"

И когда вы это делаете, не только value но и index воссоздаются для каждой итерации цикла, то есть замыкания, созданные в теге цикла, содержат ссылку на indexvalue ), созданный для этой конкретной итерации:

let divs = document.querySelectorAll("div");
for (let index = 0; index < divs.length; ++index) {
    divs[index].addEventListener('click', e => {
        alert("Index is: " + index);
    });
}

Если у вас было пять div, вы бы получили «Index is: 0», если вы нажали первый и «Index is: 4», если вы нажали последний. Это не работает, если вы используете var вместо let .

3. Правильно используйте for-in

Вы заставите людей говорить, что вы используете for-in , но это не то, for-in чего нужно. for-in запишутся через перечислимые свойства объекта , а не индексы массива. Заказ не гарантируется , даже в ES2015 (ES6). ES2015 действительно определяет порядок свойств объекта (через [[OwnPropertyKeys]] , [[Enumerate]] и все, что использует их, как Object.getOwnPropertyKeys ), но не определяет, что это будет следовать за этим порядком. (Подробности в этом другом ответе .)

Тем не менее, это может быть полезно, особенно для разреженных массивов , если вы используете соответствующие меры предосторожности:

// `a` is a sparse array
var key;
var a = [];
a[0] = "a";
a[10] = "b";
a[10000] = "c";
for (key in a) {
    if (a.hasOwnProperty(key)  &&        // These are explained
        /^0$|^[1-9]\d*$/.test(key) &&    // and then hidden
        key <= 4294967294                // away below
        ) {
        console.log(a[key]);
    }
}

Обратите внимание на две проверки:

  1. То, что объект имеет свое собственное свойство под этим именем (а не тот, который он наследует от своего прототипа), и

  2. То, что ключ представляет собой числовую строку base-10 в своей обычной строковой форме, и ее значение <= 2 ^ 32 - 2 (что составляет 4 294 967 294). Откуда это число? Это часть определения индекса массива в спецификации . Другие числа (нецелые числа, отрицательные числа, числа больше 2 ^ 32 - 2) не являются индексами массива. Причиной 2 ^ 32 - 2 является то, что делает наибольшее значение индекса менее 2 ^ 32 - 1 , что является максимальным значением, которое может иметь length массива. (Например, длина массива вписывается в 32-разрядное целое без знака.) (Подходит для RobG для указания в комментарии к моему сообщению в блоге, что мой предыдущий тест был не совсем прав.)

Это крошечный бит дополнительных накладных расходов для каждой итерации циклов на большинстве массивов, но если у вас есть разреженный массив, это может быть более эффективным способом для цикла, потому что это только петли для записей, которые на самом деле существуют. Например, для массива выше, мы зацикливаем три раза (для клавиш "0" , "10" и "10000" - помните, это строки), а не 10 001 раз.

Теперь вы не захотите писать это каждый раз, так что вы можете поместить это в свой инструментарий:

function arrayHasOwnIndex(array, prop) {
    return array.hasOwnProperty(prop) && /^0$|^[1-9]\d*$/.test(prop) && prop <= 4294967294; // 2^32 - 2
}

И тогда мы будем использовать его так:

for (key in a) {
    if (arrayHasOwnIndex(a, key)) {
        console.log(a[key]);
    }
}

Или, если вас интересует только тест «достаточно хороший для большинства случаев», вы можете использовать это, но пока оно близко, это не совсем правильно:

for (key in a) {
    // "Good enough" for most cases
    if (String(parseInt(key, 10)) === key && a.hasOwnProperty(key)) {
        console.log(a[key]);
    }
}

4. Используйте for-of (используйте итератор неявно) (ES2015 +)

ES2015 добавляет итераторы к JavaScript. Самый простой способ использования итераторов - это новый оператор for-of . Это выглядит так:

var val;
var a = ["a", "b", "c"];
for (val of a) {
    console.log(val);
}

Выход:

a
b
c

Под обложками, который получает итератор из массива и проходит через него, получает значения из него. У этого нет проблемы, связанной с использованием for-in , поскольку он использует итератор, определенный объектом (массивом), а массивы определяют, что их итераторы повторяют свои записи (а не их свойства). В отличие от for-in в ES5, порядок, в котором просматриваются записи, представляет собой числовой порядок их индексов.

5. Используйте итератор явно (ES2015 +)

Иногда вы можете явно использовать итератор. Вы тоже можете это сделать, хотя это намного clunkier чем for-of . Это выглядит так:

var a = ["a", "b", "c"];
var it = a.values();
var entry;
while (!(entry = it.next()).done) {
    console.log(entry.value);
}

Итератор - это объект, соответствующий определению Iterator в спецификации. Его next метод возвращает новый объект результата каждый раз, когда вы его вызываете. Объект result имеет свойство, done , сообщает нам, было ли это сделано, и value свойства со значением для этой итерации. ( done необязательно, если оно было бы false , value является необязательным, если оно не undefined ).

Значение value варьируется в зависимости от итератора; массивы поддерживают (по крайней мере) три функции, возвращающие итераторы:

  • values() : Это тот, который я использовал выше. Он возвращает итератор, где каждое value представляет собой запись массива для этой итерации ( "a" , "b" и "c" в примере ранее).
  • keys() : возвращает итератор, где каждое value является ключом для этой итерации (так что для нашего выше, это будет "0" , затем "1" , затем "2" ).
  • entries() : возвращает итератор, где каждое value представляет собой массив в форме [key, value] для этой итерации.

Для объектов, подобных массиву

Помимо истинных массивов, существуют также подобные массиву объекты, которые имеют свойство length и свойства с числовыми именами: экземпляры NodeList , объект arguments и т. Д. Как мы NodeList их содержимое?

Используйте любой из вышеперечисленных параметров для массивов

По крайней мере некоторые и, возможно, большинство или даже все из вышеперечисленных массивов часто применяются одинаково хорошо для объектов типа массива:

  1. Использовать forEach и связанные с ним (ES5 +)

    Различные функции на Array.prototype являются «преднамеренно генерическими» и обычно могут использоваться для объектов, подобных массиву, посредством Function#call Function#apply или Function#apply . (См. « Предостережение для объектов, предоставляемых хостом» в конце этого ответа, но это редкая проблема.)

    Предположим, вы хотели использовать forEach в свойстве childNodes . Вы сделали бы это:

    Array.prototype.forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });
    

    Если вы собираетесь сделать это много, вы можете захотеть получить копию ссылки на функцию в переменной для повторного использования, например:

    // (This is all presumably in some scoping function)
    var forEach = Array.prototype.forEach;
    
    // Then later...
    forEach.call(node.childNodes, function(child) {
        // Do something with `child`
    });
    
  2. Используйте простой цикл

    Очевидно, простой цикл for применяется к объектам, подобным массиву.

  3. Правильно использовать for-in

    for-in с теми же гарантиями, что и с массивом, должен работать и с подобными массиву объектами; может потребоваться оговорка для объектов, предоставленных хостом, на № 1 выше.

  4. Использовать for-of (использовать итератор неявно) (ES2015 +)

    for-of будет использовать итератор, предоставляемый объектом (если таковой имеется); мы должны будем увидеть, как это происходит с различными подобными массивом объектами, особенно с хост-файлами. Например, спецификация NodeList из NodeList была обновлена ​​для поддержки итерации. Спецификацию для HTMLCollection из getElementsByTagName не было.

  5. Использовать итератор явно (ES2015 +)

    См. № 4, нам нужно посмотреть, как разворачиваются итераторы.

Создать истинный массив

В других случаях вы можете преобразовать объект, подобный массиву, в истинный массив. Делать это на удивление легко:

  1. Использовать метод slice массивов

    Мы можем использовать метод slice массивов, который, как и другие методы, упомянутые выше, является «преднамеренно общим» и поэтому может использоваться с подобными массиву объектами, например:

    var trueArray = Array.prototype.slice.call(arrayLikeObject);
    

    Так, например, если мы хотим преобразовать NodeList в настоящий массив, мы могли бы сделать это:

    var divs = Array.prototype.slice.call(document.querySelectorAll("div"));
    

    См. « Предостережение для объектов, предоставляемых хостом» ниже. В частности, обратите внимание, что это не удастся в IE8 и ранее, что не позволяет использовать объекты, предоставленные хостом, как this .

  2. Использовать синтаксис распространения ( ... )

    Также возможно использовать синтаксис распространения ES2015 с механизмами JavaScript, которые поддерживают эту функцию:

    var trueArray = [...iterableObject];
    

    Так, например, если мы хотим преобразовать NodeList в истинный массив, с синтаксисом распространения это становится довольно кратким:

    var divs = [...document.querySelectorAll("div")];
    
  3. Используйте Array.from (spec) | (MDN)

    Array.from (ES2015 +, но легко поли заполняется) создает массив из объекта, подобный массиву, в случае необходимости сначала передавая записи через функцию сопоставления. Так:

    var divs = Array.from(document.querySelectorAll("div"));
    

    Или, если вы хотите получить массив имен тегов для элементов с заданным классом, вы должны использовать функцию сопоставления:

    // Arrow function (ES2015):
    var divs = Array.from(document.querySelectorAll(".some-class"), element => element.tagName);
    
    // Standard function (since `Array.from` can be shimmed):
    var divs = Array.from(document.querySelectorAll(".some-class"), function(element) {
        return element.tagName;
    });
    

Предостережение для объектов, предоставляемых хостом

Если вы используете функции Array.prototype с объектами, подобными хостам (списки DOM и другие вещи, предоставляемые браузером, а не движком JavaScript), вы должны быть уверены, что будете тестировать в своих целевых средах, чтобы убедиться, что предоставленный хост объект ведет себя правильно. Большинство из них ведут себя правильно (сейчас), но важно проверить. Причина в том, что большинство методов Array.prototype которые вы, вероятно, захотите использовать, полагаются на предоставленный хостом объект, давая честный ответ на абстрактную [[HasProperty]] . На момент написания этой статьи браузеры очень хорошо справились с этим, но спецификация 5.1 позволила предположить, что объект, предоставляемый хостом, может быть не честным. Это в §8.6.2 , несколько абзацев ниже большой таблицы в начале этого раздела), где говорится:

Хост-объекты могут реализовывать эти внутренние методы любым способом, если не указано иное; например, одна возможность заключается в том, что [[Get]] и [[Put]] для определенного объекта хоста действительно извлекают и сохраняют значения свойств, но [[HasProperty]] всегда генерируют false .

(Я не мог найти эквивалентную формулировку в спецификации ES2015, но она все еще имеет место.) Снова, на момент написания общих объектов, подобных хосту, в современных браузерах [например, экземпляры NodeList ] ручка [[HasProperty]] правильно, но это важно проверить.)


Наиболее близким к вашей идее будет использование, Array.forEach()которое принимает функцию clojure, которая будет выполняться для каждого элемента массива.

myArray.forEach(
  (item) => {
    // do something 
    console.log(item);
  }
);

Другим жизнеспособным способом было бы использовать то, Array.map()что работает одинаково, но также и mutatesкаждый элемент и возвращает его так:

var myArray = [1, 2, 3];
myArray = myArray.map(
  (item) => {
    return item + 1;
  }
);

console.log(myArray); // [2, 3, 4]

var a = ["car", "bus", "truck"]
a.forEach(function(item, index) {
    console.log("Index" + index);
    console.log("Element" + item);
})

Есть три реализации foreachв jQuery следующим образом .

var a = [3,2];

$(a).each(function(){console.log(this.valueOf())}); //Method 1
$.each(a, function(){console.log(this.valueOf())}); //Method 2
$.each($(a), function(){console.log(this.valueOf())}); //Method 3

Если вы хотите использовать forEach(), это будет выглядеть как -

theArray.forEach ( element => { console.log(element); });

Если вы хотите использовать for(), это будет выглядеть как -

for(let idx = 0; idx < theArray.length; idx++){ let element = theArray[idx]; console.log(element); }


Если вы хотите перебрать массив, используйте стандартный трехсекционный цикл.

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

Вы можете получить некоторую оптимизацию производительности, кэшируя myArray.length или повторяя ее назад.


ECMAScript5 (версия на Javascript) для работы с массивами.

forEach - Итерирует через каждый элемент массива и делает все, что вам нужно с каждым элементом.

['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

В случае, более заинтересованный в работе над массивом с использованием некоторой встроенной функции.

map - Создает новый массив с результатом функции обратного вызова. Этот метод хорош для использования, когда вам нужно отформатировать элементы вашего массива.

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

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

уменьшить. Как видно из названия, он уменьшает массив до одного значения, вызывая передачу данной функции в элементе currenct и результате предыдущего выполнения.

[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

each - Возвращает true или false, если все элементы массива проходят тест в функции обратного вызова.

// 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 - очень похоже на каждый, кроме того, что фильтр возвращает массив с элементами, возвращающими true для данной функции.

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

// Output: [2,4,6]

Надеюсь, это будет полезно.


Использование циклов с помощью механизма destructuring и распространения ES6

Разрушение и использование оператора с расширенными возможностями оказались весьма полезными для новичков ES6 как более понятных для человека / эстетических, хотя некоторые ветераны javascript могут считать его грязным, юниоры или некоторые другие люди могут оказаться полезными.

Следующие примеры будут использовать for...ofоператор и .forEachметод.

Примеры 6, 7 и 8 могут быть использованы с какими - либо функциональными петлями , такими как .map, .filter, .reduce, .sort, .every, .some, для получения дополнительной информации об этих методах проверить массив объекты .

Пример 1: Нормальный for...ofцикл - здесь нет трюков.

let arrSimple = ['a', 'b', 'c'];

for (let letter of arrSimple) {
  console.log(letter);
}

Пример 2: Разделить слова на символы

let arrFruits = ['apple', 'orange', 'banana'];

for (let [firstLetter, ...restOfTheWord] of arrFruits) {
  // Create a shallow copy using the spread operator
  let [lastLetter] = [...restOfTheWord].reverse();
  console.log(firstLetter, lastLetter, restOfTheWord);

}

Пример 3: Циклический с keyиvalue

// let arrSimple = ['a', 'b', 'c'];

// Instead of keeping an index in `i` as per example `for(let i = 0 ; i<arrSimple.length;i++)`
// this example will use a multi-dimensional array of the following format type: 
// `arrWithIndex: [number, string][]`

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Same thing can be achieved using `.map` method
// let arrWithIndex = arrSimple.map((i, idx) => [idx, i]);

// Same thing can be achieved using `Object.entries`
// NOTE: `Object.entries` method doesn't work on internet explorer unless it's polyfilled
// let arrWithIndex = Object.entries(arrSimple);

for (let [key, value] of arrWithIndex) {
  console.log(key, value);
}

Пример 4: Получить свойства объекта inline

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];

for (let { name, age: aliasForAge } of arrWithObjects) {
  console.log(name, aliasForAge);
}

Пример 5. Получите глубокие свойства объекта, что вам нужно.

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

for (let { name, tags: [firstItemFromTags, ...restOfTags] } of arrWithObjectsWithArr) {
  console.log(name, firstItemFromTags, restOfTags);
}

Пример 6: Используется ли пример 3 с.forEach

let arrWithIndex = [
  [0, 'a'],
  [1, 'b'],
  [2, 'c'],
];

// Not to be confused here, `forEachIndex` is the real index
// `mappedIndex` was created by "another user", so you can't really trust it

arrWithIndex.forEach(([mappedIndex, item], forEachIndex) => {
  console.log(forEachIndex, mappedIndex, item);
});

Пример 7: Используется ли пример 4 с.forEach

let arrWithObjects = [{
    name: 'Jon',
    age: 32
  },
  {
    name: 'Elise',
    age: 33
  }
];
// NOTE: Destructuring objects while using shorthand functions 
// are required to be surrounded by parenthesis
arrWithObjects.forEach( ({ name, age: aliasForAge }) => {
  console.log(name, aliasForAge)
});

Пример 8: Используется ли пример 5 с.forEach

let arrWithObjectsWithArr = [{
    name: 'Jon',
    age: 32,
    tags: ['driver', 'chef', 'jogger']
  },
  {
    name: 'Elise',
    age: 33,
    tags: ['best chef', 'singer', 'dancer']
  }
];

arrWithObjectsWithArr.forEach(({
  name,
  tags: [firstItemFromTags, ...restOfTags]
}) => {
  console.log(name, firstItemFromTags, restOfTags);
});


Если вы используете библиотеку jQuery , вы можете использовать jQuery.each :

$.each(yourArray, function(index, value) {
  // do your stuff here
});

РЕДАКТИРОВАТЬ :

В соответствии с вопросом пользователь хочет код в javascript вместо jquery, поэтому редактирование

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

Это итератор для N-редкого списка, где индекс начинается с 0, что является типичным сценарием при работе с document.getElementsByTagName или document.querySelectorAll)

function each( fn, data ) {

    if(typeof fn == 'string')
        eval('fn = function(data, i){' + fn + '}');

    for(var i=0, L=this.length; i < L; i++) 
        fn.call( this[i], data, i );   

    return this;
}

Array.prototype.each = each;  

Примеры использования:

Пример №1

var arr = [];
[1, 2, 3].each( function(a){ a.push( this * this}, arr);
arr = [1, 4, 9]

Пример №2

each.call(document.getElementsByTagName('p'), "this.className = data;",'blue');

Каждый тэг получает class="blue"

Пример № 3

each.call(document.getElementsByTagName('p'), 
    "if( i % 2 == 0) this.className = data;",
    'red'
);

Каждый другой тег p получает class="red">

Пример №4

each.call(document.querySelectorAll('p.blue'), 
    function(newClass, i) {
        if( i < 20 )
            this.className = newClass;
    }, 'green'
);

И, наконец, первые 20 синих p-тэгов изменены на зеленый

Предостережение при использовании функции string как функции: функция создается вне контекста и должна использоваться только там, где вы уверены в переменном охвате. В противном случае лучше передать функции, где область обзора более интуитивно понятна.


В языке JavaScript нет никакого for eachцикла . Вы можете использовать библиотеки для получения этой функции (я рекомендую Underscore.js ), используйте простой цикл.JavaScriptUnderscore.jsfor

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

Обратите внимание, что могут быть причины использовать еще более простой forцикл (см. Вопрос «Переполнение стека». Почему используется «для ... в» с итерацией массива такая плохая идея? )

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

Резюме:

При повторении массива мы часто можем достичь одной из следующих целей:

  1. Мы хотим перебрать массив и создать новый массив:

    Array.prototype.map

  2. Мы хотим перебрать массив и не создавать новый массив:

    Array.prototype.forEach

    for..of петля

В JS существует множество способов достижения обеих этих целей. Однако некоторые из них более примитивны, чем другие. Ниже вы можете найти некоторые общепринятые методы (наиболее удобные imo) для выполнения итерации массива в javascript.

Создание нового массива: Map

map()- это функция, на Array.prototypeкоторой можно преобразовать каждый элемент массива, а затем возвращает новый массив. map()принимает в качестве аргумента функцию обратного вызова и работает следующим образом:

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

let newArr = arr.map((element, index, array) => {
  return element * 2;
})

console.log(arr);
console.log(newArr);

Обратный вызов, который мы передали в map()качестве аргумента, выполняется для каждого элемента. Затем возвращается массив, который имеет ту же длину, что и исходный массив. В этом новом элементе массива преобразуется функция обратного вызова, переданная в качестве аргумента map().

Четкое различие между mapи другим циклом цикла forEachи for..ofциклом заключается в том , что mapвозвращается как новый массив и оставляет старый массив неповрежденным (за исключением случаев, когда вы просто манипулируете им с такими мыслями splice).

Также обратите внимание, что mapобратный вызов функции предоставляет в качестве второго аргумента номер индекса текущей итерации. Кроме того, третий аргумент предоставляет массив, на который mapбыл вызван. Иногда эти свойства могут быть очень полезными.

Использование Loop forEach

forEach- это функция, которая находится на Array.prototypeкоторой принимает функцию обратного вызова в качестве аргумента. Затем он выполняет эту функцию обратного вызова для каждого элемента массива. В отличие от map()функции функция forEach возвращает ничего ( undefined). Например:

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

arr.forEach((element, index, array) => {

  console.log(element * 2);

  if (index === 4) {
    console.log(array)
  }
  // index, and oldArray are provided as 2nd and 3th argument by the callback

})

console.log(arr);

Подобно mapфункции, forEachобратный вызов предоставляет в качестве второго аргумента номер индекса текущей итерации. Также третий аргумент предоставляет массив, на который forEachбыл вызван.

Прокрутка элементов с использованием for..of

for..ofПетли петли через каждый элемент массива (или любого другого объекта Iterable). Он работает следующим образом:

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

for(let element of arr) {
  console.log(element * 2);
}

В приведенном выше примере elementиспользуется элемент массива и arrмассив, который мы хотим создать . Не то, чтобы имя было elementпроизвольным, и мы могли бы выбрать любое другое имя типа «el» или что-то более декларативное, когда это применимо.

Не путайте for..inпетлю с for..ofпетлей. for..inбудет циклически проходить через все перечислимые свойства массива, тогда как for..ofцикл будет циклически проходить через элементы массива. Например:

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

arr.foo = 'foo';

for(let element of arr) {
  console.log(element);
}

for(let element in arr) {
  console.log(element);
}


Некоторые языки C стиля используют foreach для циклического перебора. В JavaScript это делается с помощью for..in цикла for..in :

var index,
    value;
for (index in obj) {
    value = obj[index];
}

Есть улов. for..in будет проходить через каждый из перечислимых элементов объекта и членов на его прототипе. Чтобы избежать считывания значений, которые наследуются через прототип объекта, просто проверьте, принадлежит ли свойство объекту:

for (i in obj) {
    if (obj.hasOwnProperty(i)) {
        //do stuff
    }
}

Кроме того, ECMAScript 5 добавил метод forEach к Array.prototype который можно использовать для перечисления по массиву с использованием calback (полиполк находится в документах, поэтому вы можете использовать его для старых браузеров):

arr.forEach(function (val, index, theArray) {
    //do stuff
});

Важно отметить, что Array.prototype.forEach не Array.prototype.forEach , когда обратный вызов возвращает false . jQuery и Underscore.js предоставляют свои собственные варианты для создания циклов, которые могут быть закорочены.


Изменить : этот ответ безнадежно устарел. Для более современного подхода рассмотрите методы, доступные в массиве . Способы, представляющие интерес, могут быть:

  • для каждого
  • карта
  • фильтр
  • застежка-молния
  • уменьшить
  • каждый
  • немного

Стандартный способ итерации массива в JavaScript - это ваниль for -loop:

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

Обратите внимание, однако, что этот подход хорош только при наличии плотного массива, и каждый индекс занят элементом. Если массив разрежен, вы можете столкнуться с проблемами производительности при таком подходе, поскольку вы будете перебирать множество индексов, которые на самом деле не существуют в массиве. В этом случае идея a for .. in -loop может быть лучшей идеей. Тем не менее , вы должны использовать соответствующие меры предосторожности, чтобы гарантировать, что действуют только желаемые свойства массива (то есть элементы массива), поскольку for..in -loop также будет перечисляться в устаревших браузерах или если дополнительный свойства определяются как enumerable .

В ECMAScript 5 будет использоваться метод forEach для прототипа массива, но он не поддерживается в старых браузерах. Поэтому, чтобы иметь возможность использовать его последовательно, вы должны либо иметь среду, которая его поддерживает (например, Node.js для JavaScript на стороне сервера), либо использовать «Polyfill». Однако Polyfill для этой функции тривиальна, и поскольку она упрощает чтение кода, это хороший полиполк.


Существует несколько способов циклического преобразования массива в JavaScript, как показано ниже:

для - это самый распространенный. Полный блок кода для циклирования

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, пока выполняется условие. Кажется, это самый быстрый цикл

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

do / while - также цикл через блок кода, пока условие истинно, будет выполняться как минимум один раз

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

Функциональные циклы - forEach, map, filter, и reduce(они цикл через функцию, но используются , если вам нужно что - то делать с вашим массивом и т.д.

// 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>

Для получения дополнительной информации и примеров о функциональном программировании на массивах, посмотрите на сообщение в блоге. Функциональное программирование в JavaScript: отображение, фильтрация и уменьшение .


Реализация forEach ( см. В jsFiddle ):

function forEach(list,callback) {
  var length = list.length;
  for (var n = 0; n < length; n++) {
    callback.call(list[n]);
  }
}

var myArray = ['hello','world'];

forEach(
  myArray,
  function(){
    alert(this); // do something
  }
);

Вы можете вызвать forEach Как это:

let Array = [1,3,2];

theArray.forEach((element)=>{ 
  // use the element of the array
  console.log(element) 
}

элемент будет иметь значение каждого индекса от 0 до длины массива.

Выход:

1    
3    
2

Explaination:

forEach находится в классе прототипов. вы также можете назвать это какArray.prototype.forEach (...);

прототип: https://hackernoon.com/prototypes-in-javascript-5bba2990e04b

Вы также можете изменить массив таким образом:

for(let i=0;i<theArray.length;i++){
  console.log(i); //i will have the value of each index
}

Строгий режим делает несколько изменений в обычной семантике JavaScript:

  • устраняет некоторые ошибки JavaScript без ошибок, изменяя их, чтобы выбросить ошибки.

  • исправляет ошибки, которые затрудняют выполнение JavaScript-движков.

  • запрещает некоторый синтаксис, который может быть определен в будущих версиях ECMAScript.

для получения дополнительной информации vistit Strict Mode - Javascript





javascript arrays loops foreach iteration