Цикл через массив в JavaScript

В Java вы можете использовать цикл for для перемещения объектов в массиве следующим образом:

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

Можете ли вы сделать то же самое в JavaScript?

2416
задан Mark Szymanski 10 июня '10 в 3:04
источник поделиться
35 ответов
  • 1
  • 2

Используйте последовательный цикл 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 следует избегать, этот оператор предназначен для перечислять свойства объекта.

Он не должен использоваться для объектов типа массива, потому что:

  • Порядок итераций не гарантируется, индексы массива могут не посещаться в числовом порядке.
  • Унаследованные свойства также перечислены.

Второй момент заключается в том, что он может дать вам массу проблем, например, если вы расширяете объект 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 позволяет вам перечислять только собственные свойства, что он, только свойства, которые физически имеет объект, не имеет наследуемых свойств.

Я бы порекомендовал вам прочитать следующую статью:

3053
ответ дан CMS 10 июня '10 в 3:07
источник поделиться

Да, но только если ваша реализация включает в себя for... of функции, введенной в ECMAScript 2015 (далее "Harmony" релиз).

Он работает следующим образом:

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

Или еще лучше, поскольку ECMAScript 2015 также предоставляет переменные с блочным диапазоном через let и const:

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

Многие разработчики JavaScript все еще работают в среде, которая еще не существует, особенно, если писать код для работы в веб-браузерах, где разработчики сайтов часто не могут быть уверены в том, какой браузер/версия будут использовать их клиенты.

Если вы можете предположить, что интерпретатор JavaScript совместим с предыдущей версией спецификации ECMAScript (которая исключает, например, версии Internet Explorer до 9), вы можете использовать метод forEach вместо цикла. В этом случае вы передаете функцию, которая будет вызываться для каждого элемента массива:

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 в состоянии цикла) может существенно myStringArray.length на производительность, поскольку она пропускает поиск свойств каждый раз; используя Rhino на моей машине, ускорение составляет 43%.

Вы часто увидите кеширование длины, выполненное в предложении инициализации цикла, например:

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

Синтаксис for... in синтаксисе, упомянутый другими, предназначен для перебора свойств объекта; поскольку Array в JavaScript - это просто объект с именами числовых свойств (и автоматически обновляемое свойство length), вы можете теоретически перебрать его с помощью массива. Но проблема в том, что он не ограничивается численными значениями свойств (помните, что даже методы на самом деле являются просто свойствами, значение которых является замыканием), равно как и не перебирает их в числовом порядке. Поэтому синтаксис for... in не должен использоваться для циклического перемещения по массивам.

869
ответ дан Mark Reed 16 апр. '12 в 5:03
источник поделиться

Вы можете использовать map, которая представляет собой метод функционального программирования, который также доступен на других языках, таких как Python и Haskell.

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

Общий синтаксис:

array.map(func)

В общем случае func принимает один параметр, который является элементом массива. Но в случае JavaScript он может принимать второй параметр, который является индексом элемента, и третьим параметром, который является самим массивом.

Возвращаемое значение array.map - это другой массив, поэтому вы можете использовать его следующим образом:

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

И теперь x - [10,20,30,40].

Вам не нужно писать функцию inline. Это может быть отдельная функция.

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.

391
ответ дан hasen 10 июня '10 в 3:09
источник поделиться

В JavaScript не рекомендуется проходить через массив с циклом for-in, но лучше использовать цикл for, например:

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

Он также оптимизирован ( "кеширование" длины массива). Если вы хотите узнать больше, прочитайте мой пост по теме.

102
ответ дан sebarmeli 07 дек. '10 в 10:24
источник поделиться

для (var s 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/ # Для петель

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

}

92
ответ дан Marlon Bernardes 11 авг. '13 в 18:54
источник поделиться

Opera, Safari, Firefox и Chrome теперь используют общий набор расширенных методов Array для оптимизации множества общих циклов.

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

Mozilla Labs опубликовала алгоритмы, которые они и WebKit используют, так что вы можете добавить их сами.

фильтр возвращает массив элементов, удовлетворяющих определенному условию или тесту.

каждый возвращает true, если каждый элемент массива проходит тест.

some возвращает true, если кто-либо передает тест.

forEach запускает функцию для каждого элемента массива и ничего не возвращает.

map похожа на forEach, но возвращает массив результатов операции для каждого элемента.

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

Игнорируйте его, пока он вам не понадобится.

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;
})();
81
ответ дан kennebec 10 июня '10 в 5:43
источник поделиться

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

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

logs: 'one', 'two', 'three'

И для обратного порядка еще более эффективный цикл

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

logs: 'three', 'two', 'one'

Или классический цикл for

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

logs: 'one', 'two', 'three'

Ссылка: http://www.sitepoint.com/google-closure-how-not-to-write-javascript/

62
ответ дан Timo Huovinen 05 янв. '12 в 12:15
источник поделиться

вступление

С моего времени в колледже я программировал на Java, JavaScript, Pascal, ABAP, PHP, Progress 4GL, C/C++ и, возможно, на нескольких других языках, о которых я не могу сейчас думать.

В то время как все они имеют свои лингвистические особенности, каждый из этих языков разделяет многие из тех же основных понятий. Такие понятия включают процедуры/функции, IF -statements, FOR -loops и WHILE -loops.


Традиционный for -loop

Традиционный for цикла состоит из трех компонентов:

  1. Инициализация: выполняется до того, как блок look будет выполнен в первый раз
  2. Условие: проверяет условие каждый раз до того, как выполняется цикл цикла, и завершает цикл, если false
  3. Последующая мысль: выполняется каждый раз после выполнения цикла

Эти три компонента отделены друг от друга a ; символ. Содержимое для каждого из этих трех компонентов является необязательным, что означает, что for минимального цикла возможно следующее:

for (;;) {
    // Do stuff
}

Конечно, вам нужно будет включить if(condition === true) { break; } if(condition === true) { break; } или if(condition === true) { return; } if(condition === true) { return; } где-то внутри, for -loop, чтобы остановить его.

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

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 цикла является while цикл. Чтобы перебрать массив, вы можете сделать это:

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

Подобно традиционным for циклов, в while циклы поддерживаются даже самым старым из браузеров.

Также обратите внимание, что цикл while может быть переписан как цикл for. Например, в while петля ведет себя здесь выше точно так же, как это for -loop:

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

For...in и for...of

В JavaScript вы также можете сделать это:

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

Однако это следует использовать с осторожностью, поскольку во всех случаях оно не ведет себя так же, как традиционный for цикла, и есть потенциальные побочные эффекты, которые необходимо учитывать. См. Почему используется "для... в" с итерацией массива плохая идея? Больше подробностей.

В качестве альтернативы 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+ делает), а for...in требуется хотя бы Internet Explorer 10.


Array.prototype.forEach()

Альтернативой for -loops является Array.prototype.forEach(), который использует следующий синтаксис:

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

Array.prototype.forEach() поддерживается всеми современными браузерами, а также Internet Explorer 9 и более поздними Array.prototype.forEach().


Библиотеки

Наконец, многие библиотеки утилиты также имеют свои собственные изменения foreach. AFAIK, три самых популярных из них:

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);
});
48
ответ дан John Slegers 29 февр. '16 в 21:56
источник поделиться

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

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)), в то время как количество символов меньше.

Есть даже несколько раз, когда вы должны перебирать обратное, например, при повторении live NodeList, где вы планируете удалять элементы из DOM во время итерации.

35
ответ дан Phrogz 04 июня '12 в 19:26
источник поделиться

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

Общий цикл:

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

ES5 для каждого:

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

Посмотрите этот для получения подробной информации или вы также можете проверить MDN для цикла через массив в JavaScript и с помощью проверки jQuery jQuery для каждого.

26
ответ дан RizN81 23 июля '14 в 15:59
источник поделиться

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

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

Или если вы действительно хотите получить идентификатор и иметь классический цикл 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
}

Современные браузеры поддерживают методы итератора forEach, map, reduce, filter и множество других методов в Array prototype.

26
ответ дан Gabriel 17 мая '11 в 1:52
источник поделиться

Я бы полностью рекомендовал использовать библиотеку underscore.js. Он предоставляет вам различные функции, которые можно использовать для перебора массивов/коллекций.

Например:

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...
25
ответ дан Andrew Thomson 17 апр. '12 в 2:33
источник поделиться

Контур массива:

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);
}
23
ответ дан Bruno Corrêa Zimmermann 02 авг. '16 в 0:18
источник поделиться

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

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

Это решения:

1) для цикла

Для цикла - это общий способ циклирования массивов в JavaScript, но не считается самым быстрым решением для больших массивов:

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

2) Пока цикл

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

Также мы используем for in цикла for in для циклизации объектов в javascript.

Также посмотрите на функции map(), filter(), reduce() т.д. На Array в JavaScript. Они могут делать вещи гораздо быстрее и лучше, чем использовать while и for.

Это хорошая статья, если вам нравится больше узнать об асинхронных функциях над массивами в JavaScript.

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

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

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

Это также означает, что вам больше не придется писать цикл for.

Подробнее >> здесь:

20
ответ дан Alireza 27 мая '17 в 5:57
источник поделиться

Если вы используете библиотеку jQuery, рассмотрите возможность использования http://api.jquery.com/jQuery.each/

Из документации:

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

Возвраты: объект

Описание: Общая функция итератора, которая может использоваться для беспрепятственной итерации по объектам и массивам. Массивы и объекты типа массива с свойством length (например, объект аргументов функции) повторяются с помощью числового индекса от 0 до длины-1. Другие объекты повторяются через их именованные свойства.

Функция $.each() не совпадает с $(selector).each(), которая используется для итерации исключительно над объектом jQuery. Функция $.each() может использоваться для итерации по любой коллекции, будь то карта (объект JavaScript) или массив. В случае массива обратный вызов каждый раз передается индексом массива и соответствующим значением массива. (Доступ к this значению также можно получить через this ключевое слово, но Javascript всегда будет переносить this значение как Object даже если это простая строка или числовое значение.) Метод возвращает свой первый аргумент - объект, который был итерирован.

19
ответ дан justingordon 21 окт. '12 в 9:20
источник поделиться

Я еще не видел этот вариант, который мне лично нравится лучше всего:

Учитывая массив:

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/

Это работает только для массивов, которые не являются разреженными. Это означает, что на каждом индексе в массиве действительно есть значение. Тем не менее, я обнаружил, что на практике я почти никогда не использую разреженные массивы в Javascript... В таких случаях обычно проще использовать объект в качестве карты/хеш-таблицы. Если у вас есть разреженный массив и вы хотите зациклиться на 0.. length-1, вам понадобится построить for (var я = 0; я < someArray.length; ++ i), но вам все равно нужно, если внутри чтобы проверить, действительно ли элемент в текущем индексе определен.

Кроме того, как упоминает CMS в комментарии ниже, вы можете использовать это только на массивах, которые не содержат значений фальшивых значений. Массив строк из примера работает, но если у вас есть пустые строки или цифры 0 или NaN и т.д., Цикл будет прерваться преждевременно. Снова на практике это почти никогда не проблема для меня, но это то, что нужно помнить, что заставляет задуматься, прежде чем использовать его... Это может дисквалифицировать его для некоторых людей:)

Что мне нравится в этом цикле:

  • Короче писать
  • Нет необходимости в доступе (не говоря уже о кеше) свойства length
  • Элемент доступа автоматически определяется в цикле тело под названием, которое вы выбираете.
  • Совмещает очень естественно с array.push и array.splice для использования массивов, таких как списки/стеки.

Причина этого в том, что спецификация массива требует, чтобы при чтении элемента из индексa >= длина массива он вернет undefined. Когда вы пишете в такое место, оно фактически обновит длину.

Для меня эта конструкция наиболее точно эмулирует синтаксис Java 5, который мне нравится:

for (String item : someArray) {
}

... с дополнительным преимуществом, также зная о текущем индексе внутри цикла

16
ответ дан Stijn de Witt 28 февр. '13 в 16:59
источник поделиться

Самый элегантный и быстрый способ

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 08 марта '14 в 5:06
источник поделиться

Есть несколько способов сделать это в JavaScript. Первые два примера - это образцы JavaScript. Третий использует библиотеку 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 21 апр. '16 в 19:03
источник поделиться

Существует метод для итерации только собственных свойств объекта, не включая прототипов:

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.forEach с помощью es5shim.

13
ответ дан kirilloid 15 апр. '12 в 15:50
источник поделиться

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

Рекомендации

13
ответ дан Yuci 23 февр. '18 в 14:29
источник поделиться

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

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

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

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 11 янв. '14 в 23:53
источник поделиться

В 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
ответ дан Alongkorn Chetasumon 14 окт. '16 в 13:31
источник поделиться

Лучший способ, по-моему, использовать функцию Array.forEach. Если вы не можете использовать это, я бы предложил получить polyfill из MDN, чтобы сделать я доступным, это, безусловно, самый безопасный способ перебора массива в 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 26 окт. '16 в 11:51
источник поделиться

Короткий ответ: да. Вы можете сделать это:

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

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

В консоли браузера вы можете увидеть что-то вроде "element1", "element2" и т.д., напечатанных.

9
ответ дан Juanjo Salvador 17 марта '16 в 13:13
источник поделиться
var x = [4, 5, 6];
for (i = 0, j = x[i]; i < x.length; j = x[++i]) {
    console.log(i,j);
}

Много чище...

8
ответ дан staticd 06 авг. '13 в 11:03
источник поделиться

Например, я использовал в консоли Firefox:

[].forEach.call(document.getElementsByTagName('pre'), function(e){ 
   console.log(e);
})
8
ответ дан victorq10 21 окт. '14 в 10:32
источник поделиться

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

 $.each([ 52, 97 ], function( index, value ) {
      alert( index + ": " + value );
 });
6
ответ дан jj_ 30 марта '16 в 5:37
источник поделиться

Уверен, что он неэффективен и многие его презирают, но он один из ближайших к упомянутому:

var myStringArray = ["Hello","World"];
myStringArray.forEach(function(f){
    // Do something
})
6
ответ дан Daniel K. 12 дек. '15 в 6:11
источник поделиться

Это не на 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
    }
5
ответ дан Muhammad Alvin 18 апр. '12 в 17:46
источник поделиться
var myStringArray = ["hello", "World"];
myStringArray.forEach(function(val, index){
   console.log(val, index);
})
5
ответ дан Amit Jamwal 29 апр. '16 в 12:05
источник поделиться
  • 1
  • 2

Другие вопросы по меткам