Слияние массивов
Последнее, что мы рассмотрим, — это слияние двух раздельных массивов для создания нового. Предположим, у вас есть два массива good (хорошие) и bad (плохие):
let good = ["Mario", "Luigi", "Kirby", "Yoshi"];
let bad = ["Bowser", "Koopa Troopa", "Goomba"];
Чтобы совместить их, используйте метод concat для массива, который вы хотите расширить, и передайте в него второй массив в виде аргумента. В итоге будет возвращен новый массив, содержащий и good, и bad:
let goodAndBad = good.concat(bad);
console.log(goodAndBad);
В этом примере метод concat возвращает новый массив, поэтому переменная goodAndBad становится массивом, содержащим результат произведенной конкатенации. Первыми в новом массиве идут элементы good, а затем элементы bad.
Отображение, фильтрация и сокращение массивов
До сих пор мы рассматривали различные способы добавления элементов, их удаления и другие счетные операции. Помимо этого, массивы предлагают простые способы управления содержащимися в них данными. Эти простые способы представлены методами map (отображение), reduce (сокращение) и filter (фильтрация).
Консервативный способ
Прежде чем говорить о map, reduce и filter и предлагаемом ими удобстве обращения с данными, давайте рассмотрим не самый удобный подход. При этом подходе вы традиционно используете цикл for и отслеживаете свое местонахождение в массиве, испытывая при этом, мягко говоря, не самые приятные чувства.
Для наглядности давайте рассмотрим следующий массив имен:
let names = ["marge", "homer", "bart", "lisa", "maggie"];
Этот соответствующим образом названный массив names содержит список имен, написанных в нижнем регистре. Мы же хотим исправить это, сделав первую букву каждого из них заглавной. С помощью цикла for это можно сделать так:
let names = ["marge", "homer", "bart", "lisa", "maggie"];
let newNames = [];
for (let i = 0; i < names.length; i++) {
let name = names[i];
let firstLetter = name.charAt(0). toUpperCase();
newNames.push(firstLetter + name.slice(1));
}
console.log(newNames);
Обратите внимание, что мы перебираем каждый элемент, делаем первую букву заглавной и добавляем исправленное имя в новый массив newNames. Здесь нет ничего магического или сложного, но вы будете часто брать элементы массива, изменять их (или обращаться к ним) и возвращать новый массив с измененными данными. Это достаточно тривиальная задача, где задействуется много рутинного повторяющегося кода. В больших кодовых базах разбор происходящего в цикле добавляет ненужные хлопоты. Вот почему были введены методы map, filter и reduce. С их помощью вы получаете все возможности цикла for без ненужных побочных эффектов и лишнего кода. Кому бы это не понравилось?
Изменение каждого элемента с помощью map
Начнем с метода map, который мы используем для модификации всех элементов массива во что-либо другое, представленное в виде нового массива (рис. 13.6).
Рис. 13.6. Оригинальный и новый массивы
Используется map следующим образом:
let newArray = originalArray.map(someFunction);
Эта единственная строка выглядит приятно и располагающе, но изнутри является весьма сложной. Давайте с этим разберемся. Работает метод map так: вы вызываете его для массива, на который хотите воздействовать (originalArray), и передаете ему функцию (someFunction) в качестве аргумента. Функция будет выполняться для каждого элемента массива, то есть вы изначально сможете написать код для изменения всех этих элементов на ваше усмотрение. В конечном итоге вы получите новый массив, содержащий данные, полученные после выполнения функции someFunction для элементов оригинального массива. Звучит просто, не правда ли?
Теперь, вооружившись map, давайте вернемся к нашей предыдущей задаче по изменению первых букв имен в массиве на заглавные. Сначала взглянем на весь код целиком, а затем рассмотрим важные детали.
let names = ["marge", "homer", "bart", "lisa", "maggie"];
function capitalizeItUp(item) {
let firstLetter = item.charAt(0). toUpperCase();
return firstLetter + item.slice(1);
}
let newNames = names.map(capitalizeItUp);
console.log(newNames);
Разберемся, как этот код работает. Нас интересует функция capitalizeItUp, переданная в виде аргумента методу map. Эта функция выполняется для каждого элемента, и стоит обратить внимание, что текущий элемент передается ей в качестве аргумента. Для ссылки на аргумент текущего элемента вы можете использовать любое имя на ваш выбор. Мы ссылаемся на этот аргумент с помощью банального item: