Массивы и итерации - это то, что каждый программист делает ежедневно. Энтузиаст или профессионал, если вы программист, который тратит свое время на кодирование весь день, вы должны писать код для итерации по массивам (или iterables) время от времени.

Ну, итерация массива с использованием циклов for, while или do..while - это то, что делают новички. Но опытный программист не напишет простой код. Опытный программист - это тот, кто пишет максимально оптимизированный код. И у нас, в Shakunsoft, есть Полнота, Совершенство и Оптимальность в нашей ДНК 🧬. В этой статье я рассказываю, как мы перебираем массив в JavaScript.

Опытный программист не напишет простой код. Опытный программист - это тот, кто пишет максимально оптимизированный код.

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

Метод 1. Использование петель (что делают новички)

/* Logic 1: Iterate one less time than the number of elements in the array starting from 0 */
var example_array = ['10', '20', '50', '64', '76'];
for(var i=0; i < example_array.length; i++) alert(example_array[i]);

Вот JSFiddle этого кода. Это, пожалуй, самый распространенный метод, которому новичков учат в первые годы своего существования. Будь то цикл while, цикл for или цикл do..while; логика такая же: инициализировать переменную итератора i и пока i не станет меньше, чем количество элементов в массиве, выполнить итерацию по элементу ith массива и в конце каждой итерации увеличить i .

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

/* Logic 2: Iterate until we reach an undefined element */
var example_array = ['10', '20', '50', '64', '76'];
for(var i=0; example_array[i]; i++) alert(example_array[i]);

Вот JSFiddle этого кода. Как вы можете видеть здесь, условие в цикле for изменено с i < example_array.length на example_array[i]. Чем он отличается от предыдущего кода? Что ж, логика здесь НЕ состоит в том, чтобы перебирать элемент ith массива, пока i меньше количества элементов в массиве. Логика здесь состоит в том, чтобы повторять до тех пор, пока ith элемент массива не станет undefined. В нашем примере в массиве 5 элементов. Поскольку шестой элемент массива, т.е. example_array[5], равен undefined, цикл прерывается после 5 итераций, когда значение i становится 5.

А теперь давайте еще немного оптимизируем код:

/* for loop without increment statement */
var example_array = ['10', '20', '50', '64', '76'];
for(var i=0; example_array[i]; ) alert(example_array[i++]);

Вот JSFiddle этого кода. Здесь логика такая же. Единственная разница здесь в том, что мы увеличиваем i с помощью оператора постинкремента ++ внутри цикла for, а не увеличиваем его внутри оператора увеличения цикла for.

Мне лично нравится этот подход (приращение переменной итератора внутри цикла). Если переменная итератора (i в нашем случае) увеличивается внутри оператора приращения цикла for; он всегда будет увеличиваться только в конце каждой итерации. В то время как запись оператора приращения для итератора внутри цикла дает нам возможность увеличивать его в любом месте.

Например, рассмотрим пример:

// Example 1:
for (var i=0; i < SOME_CONDITION; i++)
{
    do_something_with(i);
    do_something_with(i);
    do_something_with(i);
    do_something_with(i);
    do_something_with(i);
    do_something_with(i);
    do_something_with(i);
    do_something_with(i);
    do_something_with(i);
    do_something_with(i);
    // i will increment here ONLY
}

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

// Example 2:
for (var i=0; i < SOME_CONDITION; ) // NO INCREMENT STATEMENT HERE
{
    do_something_with(i);
    do_something_with(i);
    do_something_with(i);
    do_something_with(i);
    do_something_with(i++); // We can increment i WHEREVER WE WANT
    do_something_with(i);
    do_something_with(i);
    do_something_with(i);
    do_something_with(i);
    do_something_with(i);
}

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

Я не повторяю те же примеры с while и do..while циклами. По сути, они будут делать то же, что и цикл for, с той же логикой.

Теперь давайте вернемся к сути и рассмотрим второй метод итерации массива в JavaScript.

Метод 2: использование forEach

forEach - это свойство объекта Array в JavaScript. Он позволяет вам перебирать все его элементы следующим образом:

var example_array = ['10', '20', '50', '64', '76'];
example_array.forEach(function(array_element) {alert(array_element)});

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

Теперь посмотрим, как можно сократить код с помощью функций стрелок:

var example_array = ['10', '20', '50', '64', '76'];
example_array.forEach(array_element => alert(array_element));

Вот JSFiddle этого кода.

И для этого конкретного примера, давайте еще больше оптимизируем код:

// Example 3
var example_array = ['10', '20', '50', '64', '76'];
example_array.forEach(alert);

Вот JSFiddle этого кода.

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

Обратите внимание, что этот метод оптимизации не будет работать, если в функции, передаваемой в forEach, есть несколько операторов, например

var example_array = ['10', '20', '50', '64', '76'];
example_array.forEach(array_element => {
    alert(array_element); 
    do_something_with(array_element); /* This can't execute in example 3 above */
});

Метод 3: Использование for..of (как мы перебираем массив)

Рассмотрим код ниже:

var example_array = ['10', '20', '50', '64', '76'];
for (var array_element of example_array) alert(array_element);

Вот JSFiddle этого кода. В этом методе также используется for цикл и, как и forEach, функция, здесь также вам не нужно выбирать элементы один за другим. Ключевое слово of выбирает каждый элемент массива и ссылается на него с помощью array_element.

Основное различие между Методом 2 и Методом 3, описанным выше, заключается в том, что функция forEach является свойством класса Array в JavaScript. Но for..of - это независимая функция JavaScript.

Метод 4: Использование for..in (плохой метод)

Позвольте мне объяснить, почему я называю это «плохим методом». Просто попробуйте заменить of на in в приведенном выше методе 3.

var example_array = ['10', '20', '50', '64', '76'];
for (var array_element in example_array) alert(array_element);
// Wrong method

Вот JSFiddle этого кода. Что он сделает, так это будет alert от 0 до 4, а не с 0 по 4 элемент example_array. Почему так? Потому что метод for..in не был введен для итераций массива. Он был введен для перебора всех свойств такого объекта.

for..in не был введен для итераций массива. Он был введен для перебора всех свойств объекта JavaScript.

Рассмотрим этот объект:

var example_object = {
   "color" : "red",
   "shape" : "cylindrical",
   "weight" : 20,
   "height" : 3.5,
   "contains" : "gas"
};

Теперь, если вы хотите перебрать все свойства этого объекта, сделайте следующее:

for (var property in example_object) alert(property + " : " + example_object[property]);

Вот JSFiddle этого кода.

Это будет предупреждать color : red, shape : cylindrical, weight : 20, height : 3.5, contains : gas один за другим.

Обратите внимание, что прямоугольные скобки [] в JavaScript не предназначены только для обозначения индекса массива. Они также могут обозначать свойство массива. Например, если массив example_object имеет свойство с именем color, example_object.color и example_object["color"] оба одинаковы.

Но предположим, что имя свойства является переменной, вы не можете использовать метод точки .. Вы не можете найти example_object.variable_name_of_property, так как это будет undefined. Вместо этого вам нужно написать example_object[variable_name_of_property]. Оцените этот JSFiddle.

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

var example_array = ['10', '20', '50', '64', '76'];
for (var array_element in example_array) alert(array_element);

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

var example_array = ['10', '20', '50', '64', '76'];
for (var array_element in example_array) alert(example_array[array_element]);

Вот JSFiddle этого кода.

Массивы в JavaScript имеют в качестве свойств только индексы каждого элемента. Это означает, что массив типа ['10', '20' ,'50', '64', '76'] совпадает с объектом {0 : '10', 1 : '20', 3 : '50', 4 : '64', 5 : '76'}.

Вот почему я называю это плохим методом. Не так ли?

Итак, это четыре разных метода перебора массива в JavaScript. Я не рассматривал здесь функцию map, потому что Array.map - это не просто итерация. Он предназначен для создания нового массива с элементами, в которых кое-что сделано из существующего массива. Я постараюсь осветить это позже в другой статье здесь.

Автор:

Ручир Гупта, Shakunsoft IT Solutions Pvt. ООО