В чем разница между циклами и & hellip; при повторении массивов? [Дубликат]

d = {'A': 4,'B':10}

min_v = min(zip(d.values(), d.keys()))
# min_v is (4,'A')

max_v = max(zip(d.values(), d.keys()))
# max_v is (10,'B')
2429
задан John Slegers 1 May 2018 в 10:17
поделиться

23 ответа

Да, вы можете сделать то же самое в 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) While loop

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

let i=0;

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

3) Делайте while Do, делая то же самое, что и с некоторыми различиями синтаксиса, как показано ниже:

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

Это основные способы создания javascript-циклов, но их немного больше способов сделать это.

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

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

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

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

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

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

Это также означает, что у вас никогда не будет чтобы снова написать цикл for.

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

20
ответ дан Alireza 17 August 2018 в 12:07
поделиться
  • 1
    Есть ли разница в производительности перед циклом for и циклом while при итерации через массив? У меня сложилось впечатление, что различия были в основном синтаксическими – shea 29 June 2017 в 08:33
var myStringArray = ["hello", "World"];
myStringArray.forEach(function(val, index){
   console.log(val, index);
})
5
ответ дан Amit Jamwal 17 August 2018 в 12:07
поделиться

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

Например:

_.each([1, 2, 3], function(num){ alert(num); });
=> alerts each number in turn...
25
ответ дан Andrew Thomson 17 August 2018 в 12:07
поделиться
  • 1
    Для новых исследователей этого вопроса я хотел бы указать на Lo-Dash , духовного преемника Underscore, который улучшает его во многих отношениях. – Mark Reed 11 October 2013 в 11:59
  • 2
    Зачем использовать underscore, если ECMA-262 добавлен метод forEach. Нативный код всегда лучше. – Walter Chapilliquen - wZVanG 23 June 2015 в 23:32

Существует несколько способов циклического преобразования массива в 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)
});

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

26
ответ дан Community 17 August 2018 в 12:07
поделиться
  • 1
    Жаль, что ES5 forEach не находится в верхней части ответов, потому что он наиболее точно соответствует тому, что просил OP. – Pete 30 December 2014 в 03:33

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

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
ответ дан Emile Bergeron 17 August 2018 в 12:07
поделиться
  • 1
    Кажется, что этот цикл не соответствует порядку элементов в массиве. – Deniz Ozger 26 March 2014 в 17:36
  • 2
    Мой тест был неправильным. Это правильно, показывая все LOOPS. jsperf.com/native-loop-performance/16 – molokoloco 27 March 2014 в 18:41
  • 3
    -1 для модификации массива, который не должен выполнять простой цикл. Возможно, это повлияет и на тест производительности. – Bergi 30 March 2014 в 15:49
  • 4
    @bergi прав. Этот цикл уничтожает массив, когда он проходит через него. Не то, что вы хотите в большинстве случаев. – Stijn de Witt 15 May 2014 в 18:34
  • 5
    ломается по ложным предметам. – njzk2 29 July 2014 в 15:59

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

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

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

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

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

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

35
ответ дан falsarella 17 August 2018 в 12:07
поделиться
  • 1
    jQuery для всего? – Exception 7 February 2013 в 21:03
  • 2
    Для людей, которые не получают то, что так изобретательно: выражение i-- сначала оценивается и позволяет циклу продолжать, когда он не является фальшивым ... После этого счетчик уменьшается. Как только i станет нулевым, он вырвется из цикла, так как ноль будет фальшивым значением в Javascript. – Stijn de Witt 1 March 2013 в 14:09
  • 3
    Согласовано с Исключением. Не стоит недооценивать влияние дополнительных зависимостей. Я бы советовал об этом, кроме кода, который уже сильно использует jQuery. – Stijn de Witt 31 March 2013 в 20:04
  • 4
    falsish? Вы имеете в виду ложь. Давайте все придерживаться надлежащей терминологии, чтобы избежать путаницы;) – danwellman 27 April 2013 в 08:33
  • 5
    Я видел, что термин фальшивость используется людьми, которых я считаю гуру. Если для них это достаточно, для меня это достаточно хорошо. Также, но разочарованный, чтобы увидеть, что мой комментарий, который на самом деле является онтопическим, и добавляет объяснение / проницательность, получает 0 upvotes, но комментарий, который nitpicks на члене в моем комментарии получает 4. А ну, просто вопрос приоритетов, я думаю. – Stijn de Witt 15 May 2014 в 18:23
  • 6
    & quot; Кэширование длины & quot ;? Длина сохраняется как целое число в массиве, оно не измеряется каждый раз, когда вы обращаетесь к нему. Здесь нет никакой пользы при копировании значения длины в другую переменную. – Mouscellaneous 28 January 2016 в 09:54
  • 7
    @Mousciful В эти дни, конечно, нет; в годы, прошедшие после итерации массивов JavaScript, кэширующих длину на стороне JavaScript (вместо того, чтобы достигать реализации), было четкое первичное усиление (при микрооптимизации). Например, for (var i=0,len=array.length;i<len;++i) был обычным, разумным циклом для записи. – Phrogz 28 January 2016 в 19:33
  • 8
    Обновление. В наши дни вы можете использовать Array.forEach , чтобы получить тот же эффект с встроенными массивами. – Stijn de Witt 5 June 2017 в 10:50

Используйте последовательный цикл 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])
  }
}

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

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

3074
ответ дан Flimzy 17 August 2018 в 12:07
поделиться

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

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 .

26
ответ дан Gabriel 17 August 2018 в 12:07
поделиться
  • 1
    Обратите внимание, что некоторые интерпретаторы (например, V8) будут автоматически кэшировать длину массива, если код вызывается достаточно времени, и он обнаруживает, что длина не изменяется контуром. – Phrogz 4 June 2012 в 17:28
  • 2
    Спасибо за информацию @Phrogz, правда, что есть много оптимизаций, которые может сделать VM, но поскольку у старых браузеров этого нет, все-таки лучше оптимизировать для нее, так как это так дешево. – Gabriel 26 June 2012 в 02:43
  • 3
    @Gabriel: Почему? Пожалуйста, дайте примеры в реальном мире, показывающие, что не кэширование длины на самом деле является узким местом производительности. Я следую принципу «преждевременной оптимизации - это корень всех злых». Я исправлю этот цикл, который фактически создает проблему, когда я столкнусь с ней ... – Stijn de Witt 31 March 2013 в 20:06
  • 4
    @StijndeWitt imo это просто стилистическая проблема. Честно говоря, я больше не использую для циклов вместо того, чтобы полагаться на подчеркивание для таких вещей, как _.each, _.map и т. Д., Чтобы делать это. Когда я писал петли вроде этого, я кэшировал длину прежде всего так, чтобы все мои объявления переменных находились в одном месте, в верхней части моей функции. Следуя моему совету в этом отношении, это несущественно для любого приложения реального мира. Преждевременная оптимизация очень плохая, но если оптимизация происходит из-за стилистических решений, я не думаю, что это действительно имеет значение. – Gabriel 4 April 2013 в 18:15
  • 5
    @Gabriel Я считаю, что JavaScript уже поддерживает функцию карты на массивах, не нужно вводить дополнительную библиотеку для этого. – Noz 30 July 2014 в 19:14

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

 $.each([ 52, 97 ], function( index, value ) {
      alert( index + ": " + value );
 });
7
ответ дан jj_ 17 August 2018 в 12:07
поделиться

Intro

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

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


Традиционный for -луп

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

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

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

for (;;) {
    // Do stuff
}

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

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

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

В зависимости от того, что лучше всего работает, в значительной степени зависит как от личного вкуса, так и от конкретного варианта использования.

Обратите внимание, что каждый из этих вариантов

[h27] [h27] while loop

Один из альтернатив цикла 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

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

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

Это должно использоваться с осторожностью, однако, поскольку оно не ведет себя так же, как традиционный цикл for во всех случаях, и есть потенциал побочные эффекты, которые необходимо учитывать. См. . Почему использование & quot; для ... в & quot;

В качестве альтернативы 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 & nbsp; Explorer & nbsp; 10.


Array.prototype.forEach()

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

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

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


Библиотеки

Наконец, во многих библиотеках утилиты также есть свой вариант 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);
});
49
ответ дан John Slegers 17 August 2018 в 12:07
поделиться
var x = [4, 5, 6];
for (i = 0, j = x[i]; i < x.length; j = x[++i]) {
    console.log(i,j);
}

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

8
ответ дан Kasapo 17 August 2018 в 12:07
поделиться

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

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

, но он все равно будет перебирать настраиваемые свойства.

В javascript any пользовательское свойство может быть назначено любому объекту, включая массив.

Если требуется итерация по разреженному массиву, следует использовать for (var i = 0; i < array.length; i++) if (i in array) или array.forEach с es5shim.

13
ответ дан kirilloid 17 August 2018 в 12:07
поделиться
  • 1
    Это интересно, есть ли какие-либо проблемы, которые вы испытали, кроме тех, которые упомянуты? – Daniel Sokolowski 9 October 2014 в 15:34
  • 2
    А как насчет использования for (var i in array) if (++i)? – Daniel Sokolowski 9 October 2014 в 15:40

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

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

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

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

873
ответ дан Mark Reed 17 August 2018 в 12:07
поделиться
  • 1
    Обратите внимание, что некоторые интерпретаторы (например, V8) будут автоматически кэшировать длину массива , если код называется достаточно раза, и он обнаруживает, что длина не изменяется контуром. Хотя кэширование длины по-прежнему хорошо, оно может не обеспечить ускорения скорости, когда ваш код вызывается достаточно времени, чтобы на самом деле повлиять. – Phrogz 4 June 2012 в 17:29
  • 2
    @ mark-reed Не могли бы вы объяснить, почему вы использовали i in myStringArray в своем примере? Как это может быть ложным? – Denis V 28 November 2013 в 23:08
  • 3
    @DenisV: false. a=[1,2,3,4]; delete a[2]; for (j in a) { console.log(j); } выходы 0, 1, 3 и 4. a.length все еще 5. – Mark Reed 29 November 2013 в 15:34
  • 4
    Я не предлагаю for j in a. Я демонстрирую, что проверка in не является избыточной, как вы утверждали, она показывала все индексы и показывала, что существует от 0 до length-1, которого нет. Я мог бы также напечатать 2 in a, что действительно false, несмотря на то, что вы сказали, что это невозможно. – Mark Reed 30 November 2013 в 03:14
  • 5
    @GrijeshChauhan - правильно. Например, IE через версию 8 не поддерживает его. См. этот вопрос . – Mark Reed 14 January 2014 в 17:40

для (var s of myStringArray) {

(Непосредственно отвечая на ваш вопрос: теперь вы можете!) [/ ​​g10]

Большинство других ответов верны, но они не упоминают (по состоянию на это письмо), что ECMA Script & nbsp; 6 & nbsp; 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 loop

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

}

94
ответ дан Marlon Bernardes 17 August 2018 в 12:07
поделиться
  • 1
    Если вы используете ES6, я бы предложил const s вместо var s – joeytwiddle 10 February 2018 в 07:26

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

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

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

102
ответ дан Nightfirecat 17 August 2018 в 12:07
поделиться
  • 1
    myArray.forEach (function (obj) {}); по-прежнему остается лучшим – Jan Sverre 2 January 2012 в 21:47
  • 2
    небольшое улучшение: вы можете использовать ++i вместо i++ – roberkules 12 April 2012 в 15:58
  • 3
    ++i - старая оптимизация школы, которую современные компиляторы делают для вас в цикле for с давних времен :) stackoverflow.com/a/1547433/1033348 – ngryman 15 April 2012 в 01:45
  • 4
    @Jannis .forEach имеет несколько против этого. 1) не является родным. 2) Требуется новый контекст выполнения для КАЖДОГО индекса, который является довольно дорогим и кажется излишним (см. dmitrysoshnikov.com/ecmascript/chapter-1-execution-contexts ). – Jose 8 May 2012 в 14:03
  • 5
    Вы должны быть осторожны, используя этот цикл. Я начал использовать его, и мне было сложно отслеживать ошибку из-за одной ошибки, которую я сделал. Если вы вставляете две петли, например: jsfiddle.net/KQwmL/1 . Вы должны быть осторожны, чтобы указать var len по-разному в двух циклах, иначе второй цикл будет перезаписывать первую len. – Rui Marques 30 November 2012 в 15:12

Ну, как насчет этого:

for (var key in myStringArray) {
    console.log(myStringArray[key]);
}
393
ответ дан Peter Mortensen 17 August 2018 в 12:07
поделиться
  • 1
    Нет, но это может быть более мощным. проверьте это: joelonsoftware.com/items/2006/08/01.html – hasen 10 June 2010 в 01:14
  • 2
    Этот конкретный пример, вероятно, лучше реализован с использованием Array.forEach. map предназначен для создания нового массива. – harto 10 June 2010 в 01:20
  • 3
    @hasen, метод Array.prototype.map является частью стандарта 5-го издания ECMAScript, еще не доступен для всех реализаций (например, IE его не хватает), также для итерации по массиву, я думаю, что Array.prototype.forEach более семантически правильный ... также, пожалуйста, не предлагайте утверждение for-in, см. мой ответ для получения более подробной информации :) – CMS 10 June 2010 в 01:30
  • 4
    для циклов / in не рекомендуется для перечисления массивов, так как порядок eumeration не гарантируется, и он перечисляет свойства, а не только элементы массива. Для получения дополнительной информации см. stackoverflow.com/questions/500504/… или даже принятый ответ на этот вопрос; stackoverflow.com/a/3010848/444991 – Matt 9 May 2014 в 15:25
  • 5
    ну, спасибо за обновление .. а как насчет ситуации, когда нас не волнует порядок массива? Будет ли это все еще разочаровываться? – Sambhav Sharma 9 May 2014 в 15:32
  • 6
    Он все равно будет обескуражен, поскольку перечисляет все свойства, а не только элементы массива. Два сообщения, которые я связал, чтобы объяснить это более подробно. – Matt 9 May 2014 в 15:35
  • 7
    Разница между forEach и map в том, что первая не возвращает результаты итерации. map (иногда a.k.a. collect, но очень отличается от apply), явно предназначен для преобразования каждого элемента массива в соответствующий результат; это сопоставление 1-to-1 , отсюда и название. Это часть целого семейства операций, которые включают reduce (который производит единственный результат из всего массива) и filter (который создает подмножество исходного массива) и так далее. В то время как forEach просто что-то делает с каждым элементом, семантика не определена. – Mark Reed 10 September 2014 в 18:00
  • 8
    Дополнение: IE поддерживает forEach начиная с версии 9, см. для каждого метода MSDN – rwitzel 17 April 2015 в 15:12
  • 9
    Эта точная функциональность уже является частью ответа Марка Рида. – Jesse Sielaff 12 December 2015 в 04:27
  • 10
    Downvote, потому что, если вы на самом деле не сопоставляете что-то, то использование [] .map вводит в заблуждение. [] .forEach делает семантический смысл, а также передает те же три аргумента функции. – gengkev 26 April 2016 в 23:47
  • 11
    for...in следует избегать для объектов типа Array – brk 5 December 2016 в 06:25

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

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

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 i = 0; i & lt; someArray.length; ++ i), но вам все равно нужно, если внутри цикл, чтобы проверить, действительно ли элемент в текущем индексе определен.

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

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

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

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

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

for (String item : someArray) {
}

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

16
ответ дан Stijn de Witt 17 August 2018 в 12:07
поделиться
  • 1
    Обратите внимание, что при таком подходе цикл остановится, как только он найдет значение falsey , например пустую строку 0, false, NaN, null или undefined, еще до того, как i достигнет длины, например: jsfiddle.net/prvzk/1 – CMS 28 February 2013 в 20:31
  • 2
    Условие цикла может быть (item=someArray[i]) !== undefined. – daniel1426 20 March 2014 в 16:17

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

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

logs: «один», «два», «три»

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

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

: «один», «два», «три»

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

62
ответ дан Timo Huovinen 17 August 2018 в 12:07
поделиться

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

[].forEach.call(document.getElementsByTagName('pre'), function(e){ 
   console.log(e);
})
8
ответ дан victorq10 17 August 2018 в 12:07
поделиться

Некоторые примеры использования цикла в функциональном программировании в 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);

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

Метод Array.prototype.find () возвращает значение первого элемента в массиве, которое удовлетворяет предоставленной функции тестирования.

Ссылки

15
ответ дан Yuci 17 August 2018 в 12:07
поделиться

Оптимизированный подход заключается в кэшировании длины массива и использовании одиночного шаблона 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]);
}

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

var myStringArray = ["item1","item2"],i = myStringArray.length;
while(i--) {
   // do something with fruits[i]
}
10
ответ дан Zaheer Ahmed 17 August 2018 в 12:07
поделиться

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

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
ответ дан falsarella 17 August 2018 в 12:07
поделиться
  • 1
    Для людей, которые не получают то, что так изобретательно: выражение i-- сначала оценивается и позволяет циклу продолжать, когда он не является фальшивым ... После этого счетчик уменьшается. Как только i станет нулевым, он вырвется из цикла, так как ноль будет фальшивым значением в Javascript. – Stijn de Witt 1 March 2013 в 14:09
  • 2
    falsish? Вы имеете в виду ложь. Давайте все придерживаться надлежащей терминологии, чтобы избежать путаницы;) – danwellman 27 April 2013 в 08:33
  • 3
    Я видел, что термин фальшивость используется людьми, которых я считаю гуру. Если для них это достаточно, для меня это достаточно хорошо. Также, но разочарованный, чтобы увидеть, что мой комментарий, который на самом деле является онтопическим, и добавляет объяснение / проницательность, получает 0 upvotes, но комментарий, который nitpicks на члене в моем комментарии получает 4. А ну, просто вопрос приоритетов, я думаю. – Stijn de Witt 15 May 2014 в 18:23
  • 4
    & quot; Кэширование длины & quot ;? Длина сохраняется как целое число в массиве, оно не измеряется каждый раз, когда вы обращаетесь к нему. Здесь нет никакой пользы при копировании значения длины в другую переменную. – Mouscellaneous 28 January 2016 в 09:54
  • 5
    @Mousciful В эти дни, конечно, нет; в годы, прошедшие после итерации массивов JavaScript, кэширующих длину на стороне JavaScript (вместо того, чтобы достигать реализации), было четкое первичное усиление (при микрооптимизации). Например, for (var i=0,len=array.length;i<len;++i) был обычным, разумным циклом для записи. – Phrogz 28 January 2016 в 19:33

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

var myStringArray = ["Hello","World"];
myStringArray.forEach(function(f){
    // Do something
})
393
ответ дан Peter Mortensen 17 August 2018 в 12:07
поделиться
  • 1
    Нет, но это может быть более мощным. проверьте это: joelonsoftware.com/items/2006/08/01.html – hasen 10 June 2010 в 01:14
  • 2
    Этот конкретный пример, вероятно, лучше реализован с использованием Array.forEach. map предназначен для создания нового массива. – harto 10 June 2010 в 01:20
  • 3
    @hasen, метод Array.prototype.map является частью стандарта 5-го издания ECMAScript, еще не доступен для всех реализаций (например, IE его не хватает), также для итерации по массиву, я думаю, что Array.prototype.forEach более семантически правильный ... также, пожалуйста, не предлагайте утверждение for-in, см. мой ответ для получения более подробной информации :) – CMS 10 June 2010 в 01:30
  • 4
    Разница между forEach и map в том, что первая не возвращает результаты итерации. map (иногда a.k.a. collect, но очень отличается от apply), явно предназначен для преобразования каждого элемента массива в соответствующий результат; это сопоставление 1-to-1 , отсюда и название. Это часть целого семейства операций, которые включают reduce (который производит единственный результат из всего массива) и filter (который создает подмножество исходного массива) и так далее. В то время как forEach просто что-то делает с каждым элементом, семантика не определена. – Mark Reed 10 September 2014 в 18:00
  • 5
    Дополнение: IE поддерживает forEach начиная с версии 9, см. для каждого метода MSDN – rwitzel 17 April 2015 в 15:12
  • 6
    Эта точная функциональность уже является частью ответа Марка Рида. – Jesse Sielaff 12 December 2015 в 04:27
  • 7
    Downvote, потому что, если вы на самом деле не сопоставляете что-то, то использование [] .map вводит в заблуждение. [] .forEach делает семантический смысл, а также передает те же три аргумента функции. – gengkev 26 April 2016 в 23:47
  • 8
    for...in следует избегать для объектов типа Array – brk 5 December 2016 в 06:25
Другие вопросы по тегам:

Похожие вопросы: