
Добро пожаловать в первую публикацию этой новой серии о JavaScript, которую мы называем «Уроки JavaScript», где вы сможете изучить основы JavaScript, чтобы стать лучшим разработчиком или освежить некоторые знания по наиболее часто используемым темам.
Начнем с основ. Если вы более опытный разработчик, вы можете пропустить эту начальную часть или, возможно, остаться и освежить некоторые знания.
Что такое массив?
Array в JavaScript - это глобальный объект, используемый при построении списков.
Прототип или основная функциональность Array включает методы для выполнения чтения, записи, перечисления и изменения элементов в списке. Тип и длина массива могут измениться в любое время, и данные могут храниться в несмежных позициях.
Массивы в JavaScript имеют нулевой индекс, что означает, что первая позиция массива всегда нулевая.
Создание массива
Создание массива с помощью JavaScript не требует больших усилий.
const people = ['Alex', 'Daniel', 'Rafael', 'May'];
Переменная people теперь содержит массив с 4 элементами типа string в нем, индексированными следующим образом:
- Алекс
- Даниэль
- Рафаэль
- Мая
Как видите, первая позиция массива, нулевой индекс, соответствует строке Alex. Длина этого массива - четыре.
Если вы хотите вместо этого создать пустой массив, вам необходимо:
const people = [];
Это создаст пустой массив. Длина этого массива равна нулю.
Получение длины массива
Чтобы получить длину массива, вы можете использовать свойство length:
const people = ['Alex', 'Daniel', 'Jake', 'May'];people.length; // 4
Доступ к элементу по его индексу
Чтобы получить доступ к элементу в массиве по его индексу, мы должны сделать следующее:
const people = ['Alex', 'Daniel', 'Jake', 'May'];people[1]; // Daniel
Если вы попытаетесь получить доступ к элементу по его индексу, а по данному индексу нет элемента, вы получите взамен undefined.
const people = ['Alex', 'Daniel', 'Jake', 'May'];people[4]; // undefined
Если у вас есть динамический массив и вы хотите получить доступ к последнему элементу в массиве, вы можете использовать свойство length, чтобы получить количество элементов в массиве и вычесть 1, потому что, если вы помните, массивы имеют нулевой индекс, поэтому нам нужно вычесть 1 из длины массива.
const people = ['Alex', 'Daniel', 'Jake', 'May'];people[people.length - 1]; // May
Посмотрим, что произойдет, если не вычесть 1 из свойства people.length.
const people = ['Alex', 'Daniel', 'Jake', 'May'];people[people.length]; // undefined
people.length вернет 4, а четвертая позиция массива people фактически равна undefined.
Итерация по массиву
Есть несколько способов итерации по массиву, мы собираемся узнать, как выполнять итерацию с помощью for loop и forEach функции обратного вызова. Есть также несколько других, но мы подробнее рассмотрим другие возможности итерации массива позже.
Итерация по массиву с for loop
Итерация массива с for loop, безусловно, является наиболее эффективным и быстрым способом итерации по массиву.
Во-первых, мы должны получить длину массива.
const people = ['Alex', 'Daniel', 'Jake', 'May'];
const amountOfPeople = people.length; // 4;
Теперь нам нужно построить for loop. Это одна из самых основных вещей, которую вы узнаете при изучении информатики.
for (let index = 0; index <= amountOfPeople - 1; index++) {}
Давайте посмотрим на подпись for loop.
for: это резервное слово в JavaScript, используемое для объявленияfor loop.let index = 0: это объявление переменной, которое будет использоваться для хранения индекса текущей итерации.index <= amountOfPeople - 1: это предикат, используемый для определения, следует ли продолжать выполнение цикла или закончить итерации, если предикат равенtrue, он продолжит выполнение, если предикат равенfalse, он завершит выполнение.index++: это действие, которое будет выполнено после завершения итерации. Обычно вы используете это, чтобы увеличить переменнуюindexingна единицу или любое число, которое вы хотите.
Теперь давайте склеим все вместе, чтобы построить for loop, который будет отображать имена всех людей в консоли вашего браузера.
const people = ['Alex', 'Daniel', 'Jake', 'May']; const amountOfPeople = people.length; // 4;for (let index = 0; index <= amountOfPeople - 1; index++) { console.log(people[index]); }
Если вы выполните этот код в своем терминале Node или в REPL, вы должны увидеть следующий результат:
- Алекс
- Даниэль
- Джейк
- Мая
Итерация по массиву с помощью функции обратного вызова forEach
Итерация массива с помощью обратного вызова forEach не так эффективна, как for loop, но кто-то мог бы сказать, что это более визуально привлекательно и читаемо, если производительность не важна и вы стремитесь к удобочитаемости, тогда вам следует использовать forEach. Но помните, что forEach функция обратного вызова не может быть asynchronous, и если вы попытаетесь async/await ее выполнить, это определенно вызовет у вас больше одной или двух головных болей.
Давайте посмотрим, как использовать функцию обратного вызова forEach.
const people = ['Alex', 'Daniel', 'Jake', 'May'];people.forEach(function (element, index, array) { console.log(element); });
Теперь давайте посмотрим на сигнатуру функции обратного вызова forEach, как мы это делали с for loop.
people.forEach(): как вы можете видеть здесь,.forEach()- это метод из прототипаArray(основная функциональность), и он доступен вам, потому что переменнаяpeopleявляется объектомArray.function(element, index, array): это функция обратного вызова, которая будет вызываться для каждого элемента в массиве. Эта функция передаст вам 3 параметра, чтобы вы могли их использовать, это следующие параметры:
element: текущий элемент массива в этой итерации.index: текущий индекс этой итерации.array: весь массив будет передан этому свойству на тот случай, если вам понадобится для чего-то к нему доступ.
Как видите, он может быть немного более читабельным, чем for loop, но если производительность не важна, не стесняйтесь полагаться на него по мере необходимости. Вы даже можете сделать его короче с помощью arrow function с неявным возвратом 🙃
const people = ['Alex', 'Daniel', 'Jake', 'May'];people.forEach((element, index, array) => console.log(element));
Добавление элементов в массив
Чтобы добавить элементы в массив, у нас есть несколько способов: мы можем push элемент в последнюю позицию, мы можем сохранить элемент в определенной позиции массива на основе индекса или мы можем unshift элемент в первую позицию массива . Давайте посмотрим на некоторые из этих методов добавления элементов в массив.
push элементов в массив
Мы собираемся использовать метод push() из объекта Array, чтобы добавить элемент в конец массива. Допустим, у нас есть набор фруктов, содержащий яблоко 🍎, грушу 🍐, лимон 🍋, мы купили продукты и хотели бы добавить банан 🍌, нам все равно, куда его положить, поэтому мы просто собираемся push в конце.
let fruit = ['🍎', '🍐', '🍋'];fruit.push('🍌');
Теперь массив fruit будет содержать яблоко 🍎, грушу 🍐, лимон 🍋 и банан 🍌.
Хранение элементов на основе позиции индекса
Мы собираемся использовать позицию index массива для хранения арбуза, который мы только что купили, в определенном месте в массиве fruit, который мы создали ранее.
let fruit = ['🍎', '🍐', '🍋', '🍌'];fruit[4] = '🍉';
Теперь массив fruit будет содержать яблоко 🍎, грушу 🍐, лимон 🍋, банан 🍌 и в 4-й позиции массива арбуз 🍉.
Представим, что мы купили арбуз 🍉, но у нас больше нет места в холодильнике, поэтому нам нужно вынуть фрукт, чтобы хранить арбуз 🍉. как нам это сделать? Предположим, нам больше не нужны лимоны 🍋.
let fruit = ['🍎', '🍐', '🍋', '🍌'];fruit[2] = '🍉';
После этого изменения массив fruit теперь будет содержать яблоко 🍎, грушу 🍐, арбуз 🍉 и банан 🍌. Лимон 🍋 исчез, потому что мы использовали его index позицию, чтобы сообщить массиву, что в этой конкретной позиции мы хотели бы иметь арбуз 🍉 вместо лимона 🍋.
unshift элементов в массив
Мы собираемся использовать метод unshift() из объекта Array, чтобы добавить элемент в начало массива. Допустим, у нас все еще есть этот фруктовый массив, но мы хотим добавить в него больше фруктов, потому что мы купили новый фрукт, апельсин 🍊, и мы хотели бы сохранить его на последний, потому что это самый новый фрукт, и вы всегда должны его фрукт, который вы купили раньше, чем новый фрукт.
let fruit = ['🍎', '🍐', '🍉', '🍌'];fruit.unshift('🍊');
Теперь массив fruit будет содержать апельсин 🍊, яблоко 🍎, грушу 🍐, арбуз 🍉 и банан 🍌.
Удаление элементов из массива
Мы собираемся использовать метод pop() из объекта Array, чтобы удалить последний элемент из массива. Допустим, у нас все еще есть этот фруктовый массив, но мы хотим начать есть фрукты, но мы хотим съесть те, которые мы купили недавно (не очень хорошая идея с фруктами!).
let fruit = ['🍊', '🍎', '🍐', '🍉', '🍌'];fruit.pop();
Теперь массив fruit будет содержать апельсин 🍊, яблоко 🍎, грушу 🍐 и арбуз 🍉, но банана не будет, потому что мы только что его съели 😋.
Удаление различных элементов по положению
С помощью метода splice(from, amount) из объекта Array мы можем удалить подмножество элементов в массиве по диапазону индексов. Мы предоставляем индекс from, с которого начнется вычитание, и amount элементов, которые мы хотели бы вычесть из начальной точки.
let fruit = ['🍊', '🍎', '🍐', '🍉', '🍌'];let removedElements = fruit.splice(1, 3); // ['🍎', '🍐', '🍉']fruit; // ['🍊', '🍌'];
Метод splice извлекает указанные элементы и возвращает их, чтобы вы могли использовать их отдельно как новый массив.
📣 Внимание! метод splice изменяет исходный массив, и это может привести к ошибкам в вашем коде. Вы должны попытаться добиться неизменности своего кода, чтобы легко выявлять ошибки.
Нахождение индекса элемента в массиве
Представьте, что вы хотите знать, где в вашем холодильнике находятся яблоки 🍎, как бы вы это сделали? К счастью, у объекта Array есть очень удобный метод, чтобы сообщить вам индекс элемента в массиве, этот метод - indexOf, и, учитывая элемент, он вернет вам индекс этого элемента в массиве или -1, если элемент не найдено в массиве.
let fruit = ['🍊', '🍎', '🍐', '🍉', '🍌'];let appleIndex = fruits.indexOf('🍎'); // 1
Теперь мы хотим узнать, где находится арбуз 🍉!
let fruit = ['🍊', '🍎', '🍐', '🍉', '🍌'];let watermelonIndex = fruits.indexOf('🍉'); // 3
У нас есть лимоны 🍋?
let fruit = ['🍊', '🍎', '🍐', '🍉', '🍌'];let lemonIndex = fruits.indexOf('🍋'); // -1
У нас нет лимонов 🍋 на холодильнике, поэтому переменная lemonIndex будет содержать -1.
📣 Внимание! Метод indexOf вернет index первого элемента, совпадающего с массивом. Если у вас есть несколько одинаковых элементов, будет возвращен index тот, который соответствует первому от индекса 0 до индекса n.
Другой способ найти индекс элемента в массиве
Представьте, что вы знаете, что у вас есть яблоко, но на самом деле не знаете, где оно находится в холодильнике. Как бы ты это сделал? К счастью, у нас есть метод findIndex(predicate) в объекте Array, который позволит вам получить индекс в массиве данного элемента. Этот метод принимает функцию обратного вызова в качестве основного и единственного аргумента в качестве предиката для проверки элемента, который мы хотели бы получить по его индексу, и возвращает индекс соответствующего элемента или -1, если элемент не найден в массиве.
let fruit = ['🍊', '🍎', '🍐', '🍉', '🍌'];let appleIndex = fruits.findIndex('🍎'); // 1
Где лимоны 🍋 в нашем холодильнике?
let fruit = ['🍊', '🍎', '🍐', '🍉', '🍌'];let lemonIndex = fruits.findIndex('🍋'); // -1
📣 Внимание! Метод indexOf вернет index первого элемента, совпадающего с массивом. Если у вас есть несколько одинаковых элементов, будет возвращен index тот, который соответствует первому от индекса 0 до индекса n.
Копирование массива
Копирование массивов - распространенный вариант использования во многих приложениях и сценариях. Копирование массивов - простая задача, которую можно выполнять разными способами. Мы можем использовать метод slice() из объекта Array, чтобы создать копию массива в новую переменную, или мы можем использовать новую функцию ES6 spread operator (...) для создания копии массива в новую переменную.
Использование slice для копирования массива
Мы можем использовать метод slice для дублирования массива. Этот метод не изменяет исходный массив, поэтому он остается неизменным и, следовательно, неизменяемым и лучше для избежания ошибок 🐞
let basketOne = ['🍊', '🍎', '🍐', '🍉', '🍌']; let basketTwo = basketOne.slice();basketOne; // ['🍊', '🍎', '🍐', '🍉', '🍌'] basketTwo; // ['🍊', '🍎', '🍐', '🍉', '🍌']
Использование slice для копирования части массива
Мы можем использовать метод slice(start, end) для копирования раздела массива от начальной точки (включительно) до конечной точки (исключая). Этот метод не изменяет исходный массив, поэтому он остается неизменным и, следовательно, неизменяемым и лучше для избежания ошибок 🐞
let basketOne = ['🍊', '🍎', '🍐', '🍉', '🍌']; let basketTwo = basketOne.slice(1, 3);basketOne; // ['🍊', '🍎', '🍐', '🍉', '🍌'] basketTwo; // ['🍎', '🍐']
Использование spread operator для копирования массива
Мы можем использовать ES6 spread operator (...) для дублирования массива. Этот метод также не изменяет исходный массив, поэтому он остается неизменным и, следовательно, неизменяемым и лучше для избежания ошибок 🐞
let basketOne = ['🍊', '🍎', '🍐', '🍉', '🍌']; let basketTwo = [...basketOne];basketOne; // ['🍊', '🍎', '🍐', '🍉', '🍌'] basketTwo; // ['🍊', '🍎', '🍐', '🍉', '🍌']
Как видите, оба варианта имеют одинаковый результат и не отличаются по производительности, поэтому вам решать, какой из них вы хотите использовать 🤗
Объединение массивов с concat
Мы можем использовать метод concat(Array) для объединения нескольких массивов вместе, чтобы мы могли получить массив, который будет комбинацией (объединением) других массивов. Этот метод не изменяет ни один из исходных массивов, поэтому он остается неизменным и, следовательно, неизменяемым и лучше для избежания ошибок 🐞
let basketOne = ['🍊', '🍎']; let basketTwo = ['🍐', '🍉', '🍌'];let combinedBasket = basketOne.concat(basketTwo);
После использования метода .concat(array) в массиве и передачи массива, который будет объединен, он вернет новый массив вместо изменения исходного массива. Таким образом, combinedBasket будет содержать следующие элементы: '🍊', '🍎', '🍐', '🍉', '🍌', а basketOne и basketTwo останутся нетронутыми.
Объединение массивов с spread operator
Мы можем использовать ES6 spread operator (...) для объединения нескольких массивов вместе, чтобы мы могли получить массив, который будет комбинацией (объединением) других массивов. Этот метод не изменяет ни один из исходных массивов, поэтому он остается неизменным и, следовательно, неизменяемым и лучше для избежания ошибок 🐞
let basketOne = ['🍊', '🍎']; let basketTwo = ['🍐', '🍉', '🍌'];let combinedBasket = [...basketOne, ...basketTwo];
После использования ES6 spread operator (...) в массиве и распределения обоих массивов в новый массив будет иметь тот же эффект, что и при использовании метода .concat(array). Помните, что распространение массива не приведет к изменению исходного массива. Таким образом, combinedBasket будет содержать следующие элементы: '🍊', '🍎', '🍐', '🍉', '🍌', а basketOne и basketTwo останутся нетронутыми.
Поиск элемента в массиве
С помощью метода find(predicate) из объекта Array мы можем найти первый элемент, который соответствует предикату, который мы передаем в качестве аргумента функции find. Если ни один из элементов массива не соответствует предикату, undefined будет возвращен функцией find.
let basket = ['🍊', '🍎', '🍐', '🍉', '🍌'];let watermelon = basket.find(function (element) { return element === '🍉'; });let basket = ['🍊', '🍎', '🍐', '🍉', '🍌'];let lemon = basket.find(function (element) { return element === '🍋'; });lemon; // undefined
Мы можем сделать это еще короче с arrow functions с неявным возвратом!
let basket = ['🍊', '🍎', '🍐', '🍉', '🍌'];let watermelon = basket.find((element) => element === '🍉');let basket = ['🍊', '🍎', '🍐', '🍉', '🍌'];let lemon = basket.find((element) => element === '🍋');lemon; // undefined
Проверка some элементов в массиве
С помощью метода some(predicate) из объекта Array мы можем определить, соответствуют ли некоторые элементы в массиве заданному предикату. Этот метод возвращает true или false в зависимости от того, есть ли элементы, соответствующие предикату, или нет. Этот метод также возвращает false для любого предиката пустого массива.
Представим, что мы хотим проверить, есть ли у нас в холодильнике яблоки 🍎. как нам это сделать?
let fridge = ['🍊', '🍎', '🍐', '🍉', '🍌'];let fridgeHasApples = fridge.some(function (element) { return element === '🍎'; });fridgeHasApples; // true
Давайте проверим, есть ли в нашем холодильнике лимоны 🍋!
let fridge = ['🍊', '🍎', '🍐', '🍉', '🍌'];let fridgeHasLemons = fridge.some(function (element) { return element === '🍋'; });fridgeHasLemons; // false
Ой ой! Нам нужно купить продукты, потому что у нас закончились лимоны 🍋!
Проверка элемента every в массиве
С помощью метода every(predicate) из объекта Array мы можем определить, соответствует ли каждый из элементов в массиве заданному предикату. Этот метод возвращает true или false в зависимости от того, соответствуют ли все элементы предикату или нет. Этот метод также возвращает true для любого предиката пустого массива.
Представим, что мы хотим проверить, все ли фрукты в холодильнике - яблоки 🍎. как нам это сделать?
let fridge = ['🍎', '🍎', '🍎', '🍎', '🍎'];let everythingIsApple = fridge.every(function (element) { return element === '🍎'; });everythingIsApple; // true
Давайте заглянем в холодильник с большим разнообразием фруктов!
let fridge = ['🍊', '🍎', '🍐', '🍉', '🍌'];let everythingIsApple = fridge.every(function (element) { return element === '🍎'; });everythingIsApple; // false
Использование fill для изменения элементов в массиве
С помощью метода fill(element, from, to) из объекта Array мы можем изменять значения в массиве.
Попробуем наполнить наш холодильник яблоками 🍎!
let fridge = ['', '', '', '', ''];fridge.fill('🍎');fridge; // ['🍎', '🍎', '🍎', '🍎', '🍎']
А теперь давайте попробуем наполнить холодильник грушами 🍐 но только на 2–4 места в холодильнике!
let fridge = ['', '', '', '', ''];fridge.fill('🍐', 1, 3);fridge; // ['🍎', '🍐', '🍐', '🍐, '🍎']
Теперь вам следует сделать несколько интересных вещей о методе fill.
- Если
fromне используется, по умолчанию будет 0 (ноль). - Если
fromотрицательно, он будет рассчитан какarray.length + from. - Если
toне используется, по умолчанию будет использоватьсяarray.length. - Если
toотрицательно, он будет рассчитан какarray.length + to. - Метод
fillизменяет массив, и его следует использовать осторожно, чтобы не допустить ошибок 🐞. - Если
elementявляется объектом, он скопирует ссылку на нее и заполнит массив ссылками на нее.
Сортировка элементов в массиве
С помощью метода sort(function(a, b) { }) из объекта Array мы можем сортировать элементы в массиве. Если вы не передадите функцию сортировки в качестве основного и единственного аргумента методу sort, он будет использовать строковое значение на основе его позиции в Юникоде. Этот метод изменяет исходный массив, и его следует использовать осторожно, чтобы не допустить ошибок 🐞.
let numbers = [4, 2, 3, 5, 1, 6, 9];numbers.sort(); // [1, 2, 3, 4, 5, 6, 9]
Давайте посмотрим на другой пример, но на этот раз массив будет содержать строки.
let fruit = ['bananas', 'lemons', 'apples'];fruit.sort(); // ["apples", "bananas", "lemons"]
Теперь мы собираемся представить наш собственный compare function, чтобы заставить метод sort вести себя так, как мы хотим. Представим, что у нас есть массив с сообщениями, которые представляют собой объекты следующей формы:
let post = { title: 'Hello there', createdAt: new Date('03/23/2021'), content: '...' };let posts = [ { title: 'Hello there 3', createdAt: new Date('05/23/2021'), content: '...' }, { title: 'Hello there 2', createdAt: new Date('04/23/2021'), content: '...' }, { title: 'Hello there 4', createdAt: new Date('06/23/2021'), content: '...' }, { title: 'Hello there 1', createdAt: new Date('03/23/2021'), content: '...' } ];posts.sort(function (postA, postB) { if (postA.createdAt.getTime() === postB.createdAt.getTime()) return 0; if (postA.createdAt.getTime() > postB.createdAt.getTime()) return -1; if (postA.createdAt.getTime() < postB.createdAt.getTime()) return 1; });
Мы реализовали функцию сортировки для сортировки сообщений по свойству createdAt, и поскольку это свойство содержит объект Date, мы можем использовать его функцию getTime для получения количества миллисекунд, прошедших с момента Unix Time (1 января 1970 г.), затем мы используем эти числа, чтобы сравнить, какое из них больше. Функция сортировки позволяет вам возвращать число определенным образом:
- Если функция сравнения возвращает число меньше 0, она помещает
postAв более низкий индекс, чемpostB. - Если функция сравнения возвращает число больше 0, она помещает
postBв более низкий индекс, чемpostA. - Если функция сравнения возвращает 0, она не изменит
postAилиpostBиндексы. - Функция сравнения всегда должна возвращать одно и то же значение для конкретной пары элементов a и b, а также их аргументов.
Зная это, вы можете сортировать массив любым способом. В приведенном выше примере мы меняем местами -1 и 1 и тем самым сортируем массив по убыванию.
Map (итерация) по элементам в массиве
С помощью метода map(function(element, index)) из объекта Array мы можем перебирать элементы и применять результат вызова функции к каждому из элементов и возвращать новый массив с результатами.
Давайте представим, что у нас есть корзина с фруктами, но на этот раз каждый из фруктов будет объектом JavaScript, подобным следующему:
let fruitObject = {
fruit: '🍎',
amount: 1
};
fruitObject будет содержать два свойства, одно с именем fruit, которое будет содержать сам фрукт, и свойство amount, которое будет содержать, сколько плодов у нас есть. В приведенном выше примере у нас есть одно (amount: 1) яблоко (fruit: '🍎').
Наполним холодильник фруктами!
let fridge = [
{ fruit: '🍊', amount: 1 },
{ fruit: '🍎', amount: 1 },
{ fruit: '🍐', amount: 1 },
{ fruit: '🍉', amount: 1 },
{ fruit: '🍌', amount: 1 }
];
Теперь, когда у нас есть холодильник, полный вкусных и сочных фруктов, давайте перейдем к магазинам, потому что вы всегда должны стараться, чтобы в холодильнике было полно полезных фруктов. Нам нужно учитывать, что в нашем холодильнике недостаточно места для всех фруктов, поэтому мы собираемся купить по 5 штук каждого фрукта, кроме арбуза 🍉, нам нужно только два из них, потому что он слишком большой, и мы выиграли невозможно хранить их все в нашем холодильнике. как нам это сделать?
let fridge = [ { fruit: '🍊', amount: 1 }, { fruit: '🍎', amount: 1 }, { fruit: '🍐', amount: 1 }, { fruit: '🍉', amount: 1 }, { fruit: '🍌', amount: 1 } ];let fridgeFullOfFruit = fridge.map(function (fruitObject) { if (fruitObject.fruit !== '🍉') { return { fruit: fruitObject.fruit, amount: 5 }; } else { return { fruit: fruitObject.fruit, amount: 2 }; } });
Давайте переварим то, что мы сделали выше. Мы создали новую переменную с именем fridgeFullOfFruit, в которой собирались хранить все фрукты после покупки продуктов. Затем мы map (перебираем) fruitObjects, которые хранятся в переменной fridge, и, как мы уже знаем, метод map из объекта Array это функция обратного вызова и принимает до трех аргументов:
- Элемент, который в настоящее время повторяется.
- Индекс итерации.
- Итерируемый массив.
В этом конкретном сценарии мы используем только элемент, который в настоящее время итерируется, поэтому мы можем безопасно игнорировать два других аргумента, поэтому наша функция обратного вызова имеет следующую сигнатуру function(fruitObject) {}, потому что мы используем только текущий элемент в процессе итерации .
Затем нам нужно создать логику внутри функции, которую мы хотим применить к каждому из элементов массива:
if (fruitObject.fruit !== '🍉') {
return {
fruit: fruitObject.fruit,
amount: 5
};
} else {
return {
fruit: fruitObject.fruit,
amount: 2
};
}
Мы проверяем, не является ли свойство fruit в fruitObject арбузом 🍉, и если это не так, мы собираемся вернуть fruitObject с соответствующим фруктом и количеством 5, которое является количеством фруктов, которое мы хотим купить. для всех фруктов, кроме арбузов 🍉 которых должно быть 2.
Для примера мы сделали этот код более явным, но мы можем использовать arrow functions с неявным возвратом и тернарный оператор, чтобы сделать этот код еще более компактным.
let fridge = [ { fruit: '🍊', amount: 1 }, { fruit: '🍎', amount: 1 }, { fruit: '🍐', amount: 1 }, { fruit: '🍉', amount: 1 }, { fruit: '🍌', amount: 1 } ];let fridgeFullOfFruit = fridge.map((fruitObject) => ({ ...fruitObject, amount: fruitObject.fruit !== '🍉' ? 5 : 2 }));
filter массив для поиска элементов
С помощью метода filter(function(element, index)) из объекта Array мы можем перебирать элементы и возвращать те, которые соответствуют условию, реализованному в функции обратного вызова, путем возврата true или false. Этот метод filter сгенерирует новый массив с результатами, подобными методу map.
Представим, что у нас есть тот же элемент fruitObject, который был у нас раньше в примере map.
let fruitObject = {
fruit: '🍎',
amount: 1
};
Давайте заполним холодильник всеми соответствующими фруктами, но на этот раз у некоторых из них будет 0 (ноль), и мы собираемся использовать это свойство amount, чтобы отфильтровать, какие элементы нам нужно купить, чтобы мы могли пополнить холодильник с.
let fridge = [
{ fruit: '🍊', amount: 0 },
{ fruit: '🍎', amount: 1 },
{ fruit: '🍐', amount: 0 },
{ fruit: '🍉', amount: 1 },
{ fruit: '🍌', amount: 0 }
];
Теперь нам нужно filter все это fruitObjects, чтобы определить, какие из них нам нужно приобрести, на основе свойства amount каждого из этих объектов. как нам это сделать?
let fridge = [ { fruit: '🍊', amount: 0 }, { fruit: '🍎', amount: 1 }, { fruit: '🍐', amount: 0 }, { fruit: '🍉', amount: 1 }, { fruit: '🍌', amount: 0 } ];let shoppingList = fridge.filter(function (fruitObject) { if (fruitObject.amount === 0) { return true; } else { return false; } });
После фильтрации массива fridge с помощью данной функции обратного вызова у нас будет новый массив (переменная shoppingList), содержащий следующее:
[
{ fruit: '🍊', amount: 0 },
{ fruit: '🍐', amount: 0 },
{ fruit: '🍌', amount: 0 }
];
В качестве бонуса теперь мы можем отображать этот новый массив shoppingList, чтобы покупать продукты!
let shoppingList = [ { fruit: '🍊', amount: 0 }, { fruit: '🍐', amount: 0 }, { fruit: '🍌', amount: 0 } ];let shoppingBasket = shoppingList.map((fruitObject) => ({ ...fruitObject, amount: 5 }));
Теперь у нас есть корзина со свежими и сочными фруктами! 😋
reduce значения массива в одно значение
С помощью метода reduce(function(accumulator, value, index), initialValue) из объекта Array мы можем перебирать элементы и возвращать одно значение. Второй аргумент функции reduce - initialValue, который будет использоваться как начальное значение для аккумулятора. Если вы ничего не передаете в качестве этого аргумента, оно будет использовать первое значение массива и будет пропущено. Я рекомендую всегда передавать что-то в этот аргумент, чтобы быть более ясным в отношении того, что вы ожидаете получить в конце, плюс, если вы используете TypeScript, вы получите очень хороший intellisense по этому поводу 🙃
Давайте еще раз представим, что у нас есть холодильник, полный фруктов в форме объекта javascript, подобного следующему:
let fruitObject = {
fruit: '🍎',
amount: 1
};
А теперь хотим проверить, сколько всего фруктов у нас хранится в холодильнике. как нам это сделать?
let fridge = [ { fruit: '🍊', amount: 2 }, { fruit: '🍎', amount: 4 }, { fruit: '🍐', amount: 1 }, { fruit: '🍉', amount: 0 }, { fruit: '🍌', amount: 3 } ];let amountOfFruits = fridge.reduce(function (accumulated, fruitObject) { return accumulated + fruitObject.amount; }, 0);amountOfFruits; // 2 + 4 + 1 + 0 + 3 = 10
Метод reduce - очень удобная функция, когда вы хотите работать с массивами, чтобы получить от них какое-то значение, но вы всегда должны помнить, что эта функция требует больших вычислительных ресурсов, поэтому, если вы можете, вы должны попытаться избежать ее, если вы Бюджет ЦП мал или вы хотите, чтобы ваше приложение работало как можно лучше. В качестве более производительной альтернативы вы можете, например, использовать for loop, как показано ниже, потому что оно того стоит 👌🏻
let fridge = [ { fruit: '🍊', amount: 2 }, { fruit: '🍎', amount: 4 }, { fruit: '🍐', amount: 1 }, { fruit: '🍉', amount: 0 }, { fruit: '🍌', amount: 3 } ];let amountOfFruits = 0; let fruitsOnTheFridge = fridge.length;for (let index = 0; index <= fruitsOnTheFridge; index++) { amountOfFruits += fridge[index].amount; }amountOfFruits; // 2 + 4 + 1 + 0 + 3 = 10
Обход массива с помощью цикла for of
Другой способ перебора массива - использование цикла for of, это очень простой и читаемый тип цикла.
Переберем фрукты на холодильнике!
let fridge = [ { fruit: '🍊', amount: 2 }, { fruit: '🍎', amount: 4 }, { fruit: '🍐', amount: 1 }, { fruit: '🍉', amount: 0 }, { fruit: '🍌', amount: 3 } ];for (let fruit of fridge) { console.log(fruit); }// {fruit: "🍊", amount: 2} // {fruit: "🍎", amount: 4} // {fruit: "🍐", amount: 1} // {fruit: "🍉", amount: 0} // {fruit: "🍌", amount: 3}
Как видно из фрагмента кода выше, это гораздо более простой способ перебора массива. Для каждой итерации он сохраняет значение текущего элемента индекса в переменной fruit, и вы можете использовать его для управления им по своему усмотрению.
Создание массива from
С помощью метода from(arrayLikeObject, mapFunction) из объекта Array мы можем создать новый Array из итерируемого объекта.
let fruitsString = '🍊🍎🍐🍉🍌'; let fruits = Array.from(fruitsString);fruits; // ['🍊', '🍎', '🍐', '🍉', '🍌']
В приведенном выше примере мы использовали строку, в JavaScript строка представляет собой объект, подобный массиву, потому что он имеет свойство length, но также можно использовать любой объект, имеющий свойство length или индексированные элементы. Также здесь можно использовать объекты Map и Set, потому что они итерируемы, а значит, совершенно допустимы.
Второй аргумент метода from - это функция обратного вызова, используемая для перебора элементов после их создания, что означает, что мы можем, например, применить некоторую логику к каждому из них, например:
let fruitsString = '🍊🍎🍐🍉🍌'; let fruits = Array.from(fruitsString, function (element) { return { fruit: element, amount: 5 }; });// {fruit: "🍊", amount: 5} // {fruit: "🍎", amount: 5} // {fruit: "🍐", amount: 5} // {fruit: "🍉", amount: 5} // {fruit: "🍌", amount: 5}
Как видно из приведенного выше фрагмента кода, этот метод очень гибкий и мощный, и мы создали массив объектов с некоторыми настраиваемыми свойствами по своему усмотрению.
## Объединение элементов из массива в строку
С помощью метода join(separator) из объекта Array мы можем объединить элементы массива в строку.
let fruits = ['🍊', '🍎', '🍐', '🍉', '🍌']; let fruitsString = fruits.join();fruitsString; // "🍊,🍎,🍐,🍉,🍌"
Как видно из фрагмента кода выше, метод join ведет себя немного странно, когда не указан аргумент separator, потому что, если мы ничего не предоставляем, он будет использовать , (запятую) для разделения элементов. Если вы хотите, например, объединить их все вместе, вы можете указать методу join использовать пустую строку '' в качестве разделителя.
let fruits = ['🍊', '🍎', '🍐', '🍉', '🍌']; let fruitsString = fruits.join('');fruitsString; // "🍊🍎🍐🍉🍌"
Проверка, является ли значение Array.
С помощью метода isArray(object) из объекта Array мы можем определить, является ли объект, переданный в качестве основного или единственного аргумента, Array. Этот метод вернет true или false в зависимости от того, соответствует object требованиям или нет.
Давайте посмотрим, как это на самом деле ведет себя в различных положительных (true) сценариях:
Array.isArray([]); // true
Array.isArray(['🍎']); // true
Array.isArray(new Array()); // true
Array.isArray(new Array('🍎', '🍐', '🍊')); // true
Array.isArray(new Array(4)); // true
Array.isArray(Array.prototype); // true
Теперь давайте посмотрим, как это на самом деле ведет себя в различных отрицательных (false) сценариях:
Array.isArray(); // false
Array.isArray({}); // false
Array.isArray(undefined); // false
Array.isArray(null); // false
Array.isArray(4); // false
Array.isArray('OTPfy'); // false
Array.isArray(true); // false
Array.isArray(false); // false
Сглаживающие массивы
С помощью метода flat(depth) из объекта Array мы можем сгладить массив, который содержит больше массивов (подмассивов) в качестве значений.
Давайте представим, что в нашем холодильнике есть разные пакеты, в каждом из которых содержатся фрукты, и мы хотели бы извлечь все фрукты из этих пакетов, чтобы потом что-то с ними сделать. как нам это сделать?
let fridge = [ ['🍎', '🍎', '🍎', '🍎'], // apples bag ['🍐', '🍐'], // pears bag ['🍊'] // oranges bag ];let allFruits = fridge.flat();allFruits; // ["🍎", "🍎", "🍎", "🍎", "🍐", "🍐", "🍊"]
Как видно из фрагмента кода выше, метод flat очень удобен, когда мы хотим получить единый массив без вложенности. Давайте посмотрим на более сложный пример:
let fridge = [ ['🍎', '🍎', '🍎', '🍎'], // apples bag ['🍐', ['🍐', '🍐']], // pears bag [['🍊', ['🍊']], '🍊'] // oranges bag ];let allFruits = fridge.flat();allFruits; // ["🍎", "🍎", "🍎", "🍎", "🍐", ["🍐", "🍐"], ["🍊", ["🍊"]], "🍊"]
Посмотрев на вывод приведенного выше фрагмента кода, мы можем определить, что если мы не передадим какое-либо числовое значение аргументу depth метода flat, он выполнит операцию сглаживания только для строки элементов массива первого уровня.
Давайте теперь посмотрим, что произойдет, если мы передадим значение свойству depth.
let fridge = [ ['🍎', '🍎', '🍎', '🍎'], // apples bag ['🍐', ['🍐', '🍐']], // pears bag [['🍊', ['🍊']], '🍊'] // oranges bag ];let allFruits = fridge.flat(2);allFruits; // ["🍎", "🍎", "🍎", "🍎", "🍐", "🍐", "🍐", "🍊", ["🍊"], "🍊"]
Как видно из выходных данных, передавая 2 в качестве свойства depth, он выравнивает массив также по строке элементов массива второго уровня, но наш массив является трехуровневым глубоким массивом. Давайте сгладим это на depth из трех и посмотрим, что произойдет.
let fridge = [ ['🍎', '🍎', '🍎', '🍎'], // apples bag ['🍐', ['🍐', '🍐']], // pears bag [['🍊', ['🍊']], '🍊'] // oranges bag ];let allFruits = fridge.flat(2);allFruits; // ["🍎", "🍎", "🍎", "🍎", "🍐", "🍐", "🍐", "🍊", "🍊", "🍊"]
Отлично, мы достигли нашей цели - полностью свернуть массив в единый массив глубины!