Операции с массивами

Последнее обновление: 19.11.2023

Язык JavaScript предоставлет богатые возможности для работы с массивами, которые реализуются с помощью методов объекта Array:

  • concat(): объединяет элементы двух массивов в один массив

  • every(): проверяет, все ли элементы соответствуют определенному условию

  • filter(): фильтрует элементы массива

  • find(): возвращает первый элемент массива, который соответствует некоторому условию

  • findLast(): возвращает последний элемент, который соответствует условию

  • findIndex(): возвращает индекс первого элемента массива, который соответствует некоторому условию

  • findLastIndex(): возвращает индекс последнего элемента, который соответствует условию

  • flat(): упрощает структуру вложенных элементов массива.

  • forEach(): применяет определенную функцию к каждому элементу массива

  • includes(): проверяет, есть ли в массиве значение

  • indexOf(): возвращают индекс первого включения элемента в массиве.

  • join(): объединяет элементы массива в строку

  • lastIndexOf(): возвращают индекс последнего включения элемента в массиве.

  • map(): преобразует каждый элемент массива в другое значение на основе функции преобразования (проекция элементов)

  • pop(): удаление элемента с конца массива

  • push(): добавление элемента в конец массива

  • reduce(): объединяет элементы массива в одно значение

  • reverse(): располагает элементы массива в обратном порядке

  • shift(): удаляет первый элемент массива

  • slice(): вырезает отдельные элементы из массива

  • splice(): добавление элементы на определенную позицию в массиве

  • some(): проверяет, соответствует ли хотя бы один элемент условию.

  • sort(): сортирует массив

  • unshift(): добавляет новый элемент в начало массива

Рассмотрим применение этих методов

Добавление данных

push()

Метод push() добавляет элемент в конец массива:

const people = [];
people.push("Tom");
people.push("Sam");
people.push("Bob","Mike");

console.log("В массиве people элементов: ", people.length);
console.log(people); // ["Tom", "Sam", "Bob", "Mike"]

unshift()

Метод unshift() добавляет новый элемент в начало массива:

const people = ["Bob"];

people.unshift("Alice");
console.log(people);	// ["Alice", "Bob"]

people.unshift("Tom", "Sam");
console.log(people);	// ["Tom", "Sam", "Alice", "Bob"]

Добавление данных по определенному индексу

Метод splice позволяет вставить элементы на определенную позицию. Первый аргумент представляет индекс в массиве, по которому надо добавить новые элементы. Второй аргумент представляет количество элементов, которые необходимо удалить(! этот метод также применяется для удаления). Для добавления для этого аргумента устанавливается значение 0. Все остальные аргументы представляют элементы, которые необходимо добавить в массив.:

const people = ["Tom", "Sam", "Bob"];
people.splice(1, 0, "Alice");  // добавляем элемент "Alice" по индексу 1
console.log(people);         // ["Tom", "Alice", "Sam", "Bob"]

В данном случае добавляем элемент "Alice" по индексу 1.

Также можно добавляеть набор элементов, начиная с определенного индекса:

const people = ["Tom", "Sam", "Bob"];
people.splice(1, 0, "Alice", "Alex", "Kate");  // добавляем элемент "Alice" по индексу 1
console.log(people);         // ["Tom", "Alice", "Alex", "Kate", "Sam", "Bob"]

Удаление данных

pop()

Метод pop() удаляет последний элемент из массива:

const people = ["Tom", "Sam", "Bob", "Mike"];

const lastPerson = people.pop(); // извлекаем из массива последний элемент
console.log(lastPerson );	// Mike
console.log(people);	// ["Tom", "Sam", "Bob"]

В качестве результата метод pop возвращает удаленный элемент.

shift()

Метод shift() извлекает и удаляет первый элемент из массива:

const people = ["Tom", "Sam", "Bob", "Mike"];

const first = people.shift(); // извлекаем из массива первый элемент
console.log(first);	// Tom
console.log(people);	// ["Sam", "Bob", "Mike"]

Удаление элемента по индексу. splice()

Метод splice() также удаляет элементы с определенного индекса. Например, удаление элементов с третьего индекса:

const people = ["Tom", "Sam", "Bill", "Alice", "Kate"];
const deleted = people.splice(3);
console.log(deleted);       // [ "Alice", "Kate" ]
console.log(people);         // [ "Tom", "Sam", "Bill" ]

Метод splice возвращает удаленные элементы в виде нового массива.

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

const people = ["Tom", "Sam", "Bill", "Alice", "Kate"];
const deleted = people.splice(-1);
console.log(deleted);       // [ "Kate" ]
console.log(people);         // ["Tom", "Sam", "Bill", "Alice"]

Дополнительная версия метода позволяет задать количество элементов для удаления. Например, удалим с первого индекса три элемента:

const people = ["Tom", "Sam", "Bill", "Alice", "Kate"];
const deleted = people.splice(1, 3);
console.log(deleted);       // ["Sam", "Bill", "Alice"]
console.log(people);         // ["Tom", "Kate"]

Замена элементов

Метод splice() позволяет как добавлять, так и удалять элементы. Мы можем сочетать две эти возможности для замены одних элементов массива на другие. Например:

const people = ["Tom", "Sam", "Bob", "Alice", "Kate"];
const deleted = people.splice(1, 3, "Alex", "Mike");
console.log(deleted);       // ["Sam", "Bob", "Alice"]
console.log(people);         // ["Tom", "Alex", "Mike", "Kate"]

Здесь удаляем с индекса 1 (первый параметр splice) 3 элемента (второй параметр splice) и вместо них вставляет два элемента - "Alex" и "Mike"

Копирование массива

slice()

Копирование массива может быть поверхностным или неглубоким (shallow copy) и глубоким (deep copy).

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

const users = ["Tom", "Sam", "Bill"];
console.log(users);		//	["Tom", "Sam", "Bill"]
const people = users;		//	неглубокое копирование

people[1] = "Mike";		//	изменяем второй элемент
console.log(users);		//	["Tom", "Mike", "Bill"]

В данном случае переменная people после копирования будет указывать на тот же массив, что и переменная users. Поэтому при изменении элементов в people, изменятся элементы и в users, так как фактически это один и тот же массив.

Такое поведение не всегда является желательным. Например, мы хотим, чтобы после копирования переменные указывали на отдельные массивы. И в этом случае можно использовать глубокое копирование с помощью метода slice():

const users = ["Tom", "Sam", "Bill"];
console.log(users);				//	["Tom", "Sam", "Bill"]
const people = users.slice();		//	глубокое копирование

people[1] = "Mike";				//	изменяем второй элемент
console.log(users);				//	["Tom", "Sam", "Bill"]
console.log(people);			//	["Tom", "Mike", "Bill"]

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

Но тут стоит отметить, что то же самое копирование по сути можно выполнить и с помощью spread-оператора ...:

const users = ["Tom", "Sam", "Bill"];
console.log(users);     //  ["Tom", "Sam", "Bill"]
const people = [...users];
 
people[1] = "Mike";     //  изменяем второй элемент
console.log(users);     //  ["Tom", "Sam", "Bill"]
console.log(people);     //  ["Tom", "Mike", "Bill"]

Также метод slice() позволяет скопировать часть массива. Для этого он принимает два параметра:

slice(начальный_индекс, конечный_индекс)

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

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

const users = ["Tom", "Sam", "Bill", "Alice", "Kate"];
const people = users.slice(2);  // со второго индекса до конца
console.log(people);		// ["Bill", "Alice", "Kate"]

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

const users = ["Tom", "Sam", "Bill", "Alice", "Kate"];
const people = users.slice(-2);  // до второго индекса с конца
console.log(people);		// ["Alice", "Kate"]

Второй параметр позволяет ограничить выборку копируемых элементов. Например, выберем в новый массив элементы, начиная с 1 индекса по индекс 4 не включая:

const users = ["Tom", "Sam", "Bill", "Alice", "Kate"];
const people = users.slice(1, 4);
console.log(people);		// ["Sam", "Bill", "Alice"]

И поскольку индексация массивов начинается с нуля, то в новом массиве окажутся второй, третий и четвертый элемент.

Второй параметр также может быть отрицательным. В этом случае второй индекс отсчитывается с конца:

const users = ["Tom", "Sam", "Bill", "Alice", "Kate"];
const people = users.slice(2, -1);  // с индекса 2 по индекс 1 с конца
console.log(people);		// ["Bill", "Alice"]

copyWithin

Метод copyWithin() позволяет копировать элементы внутри массива. Он принимает три параметра:

copyWithin(index1,  // позиция, в которую вставляются копируемые элементы 
			index2,  // начальная позиция, с которой будут копироваться элементы 
			index3   // конечная позиция, до которой будут копироваться элементы
)

Пример применения:

const users = ["Tom", "Sam", "Bob", "Alice", "Kate"];
const people = users.copyWithin(1, 3, 5);  // элементы с индекса 3 по индекс 4 (два элемента)
                                            // копируются по индексу 1
console.log(people);    // ["Tom", "Alice", "Kate", "Alice", "Kate"]

Получение элементов вне диапазона. toSpliced

Но, возможно, мы просто хотим получить элементы вне определенного диапазона без изменения текущего массива. В этом случае мы можем использовать метод toSpliced(). Этот метод возвращает массив из элементов, которые располагаются вне диапазона:

const people = ["Tom", "Sam", "Bill", "Alice", "Kate"];
const range = people.toSpliced(1, 3);
console.log(range);       // ["Tom", "Kate"]
console.log(people);         // ["Tom", "Sam", "Bill", "Alice", "Kate"]

concat()

Метод concat() служит для объединения массивов. В качестве результата он возвращает объединенный массив:

const men = ["Tom", "Sam", "Bob"];
const women = ["Alice", "Kate"];
const people = men.concat(women);
console.log(people);         // ["Tom", "Sam", "Bob", "Alice", "Kate"]

join()

Метод join() объединяет все элементы массива в одну строку, используя определенный разделитель, который передается через параметр:

const people = ["Tom", "Sam", "Bob"];

const peopleToString = people.join("; ");
console.log(peopleToString);         // Tom; Sam; Bob

В метод join() передается разделитель между элементами массива. В данном случае в качестве разделителя будет использоваться точка с запятой и пробел ("; ").

sort() и toSorted

Метод sort() сортирует массив по возрастанию:

const people = ["Tom", "Sam", "Bob"];

people.sort();
console.log(people);         // ["Bob", "Sam", "Tom"]

Стоит отметить, что по умолчанию метод sort() рассматривает элементы массива как строки и сортирует их в алфавитном порядке. Что может привести к неожиданным результатам, например:

const numbers = [200, 15, 5, 35];

numbers.sort();
console.log(numbers);         // [15, 200, 35, 5]

Здесь мы хотим отсортировать массив чисел, но результат может нас обескуражить: [15, 200, 35, 5]. В этом случае мы можем настроить метод, передав в него функцию сортировки. Логику функции сортировки мы определяем сами:

const numbers = [200, 15, 5, 35];

numbers.sort( (a, b) =>  a - b);
console.log(numbers);         // [5, 15, 35, 200]

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

JavaScript также предоставляет метод toSorted(), которая возвращает отсортированные элементы в виде нового массива, не изменяя текущий массив:

const numbers = [200, 15, 5, 35];

const sorted = numbers.toSorted();
console.log(sorted);         // [15, 200, 35, 5]

По умолчанию метод toSorted() также сортирует в алфавитном порядке. Но также можно передать в метод функцию сравнения элементов:

const numbers = [200, 15, 5, 35];
const sorted = numbers.toSorted( (a, b) =>  a - b);
console.log(sorted);         // [5, 15, 35, 200]

reverse() и toReversed()

Метод reverse() меняет порядок элементов в массиве на обратный:

const people = ["Tom", "Sam", "Bob"];

people.reverse();
console.log(people);         // ["Bob", "Sam", "Tom"]

Метод toReversed() также меняет порядок элементов на обратный, но возвращает их в виде нового массива без изменения текущего:

const people = ["Tom", "Sam", "Bob"];

const reversed = people.toReversed();
console.log(people);         // ["Tom", "Sam", "Bob"]
console.log(reversed);         // ["Bob", "Sam", "Tom"]

Поиск индекса элемента

Методы indexOf() и lastIndexOf() возвращают индекс первого и последнего включения элемента в массиве. Например:

const people = ["Tom", "Sam", "Bob", "Tom", "Alice", "Sam"];

const firstIndex = people.indexOf("Tom");
const lastIndex = people.lastIndexOf("Tom");
const otherIndex = people.indexOf("Mike");
console.log(firstIndex); // 0
console.log(lastIndex);  // 3
console.log(otherIndex); // -1

firstIndex имеет значение 0, так как первое включение строки "Tom" в массиве приходится на индекс 0, а последнее на индекс 3.

Если же элемент отсутствует в массиве, то в этом случае методы indexOf() и lastIndexOf() возвращают значение -1.

Проверка наличия элемента

Метод includes() проверяет, есть ли в массиве значение, переданное в метод через параметр. Если такое значение есть, то метод возвращает true, если значения в массиве нет, то возвращается false. Например:

const people = ["Tom", "Sam", "Bob", "Tom", "Alice", "Sam"];

console.log(people.includes("Tom")); 	// true - Tom есть в массиве
console.log(people.includes("Kate"))	// false - Kate нет в массиве

В качестве второго параметра метод includes() принимает индекс, с которого надо начинать поиск:

const people = ["Tom", "Sam", "Bob", "Tom", "Alice", "Sam"];

console.log(people.includes("Bob", 2)); // true
console.log(people.includes("Bob", 4))	// false

В данном случае мы видим, что при поиске со 2-го индекса в массиве есть строка "Bob", тогда как начиная с 4-го индекса данная строка отсутствует.

Если если этот параметр не передается, то по умолчанию поиск идет с 0-го индекса.

При передаче отрицательного значения поиск идет с конца

const people = ["Tom", "Sam", "Bob", "Tom", "Alice", "Sam"];

console.log(people.includes("Tom", -2)); // false - 2-й индекс с конца
console.log(people.includes("Tom", -3))	// true	- 3-й индекс с конца

every()

Метод every() проверяет, все ли элементы соответствуют определенному условию:

const numbers = [ 1, -12, 8, -4, 25, 42 ];
const passed = numbers.every(n => n > 0);
console.log(passed); // false

В метод every() в качестве параметра передается функция, которая представляет условие. Эта функция в качестве параметра принимает элемент и возвращает true (если элемент соответствует условию) или false (если не соответствует).

Если хотя бы один элемент не соответствует условию, то метод every() возвращает значение false.

В данном случае условие задается с помощью лямбда-выражения n => n > 0, которое проверяет, больше ли элемент нуля.

some()

Метод some() похож на метод every(), только он проверяет, соответствует ли хотя бы один элемент условию. И в этом случае метод some() возвращает true. Если элементов, соответствующих условию, в массиве нет, то возвращается значение false:

const numbers = [ 1, -12, 8, -4, 25, 42 ];
const passed = numbers.some(n => n > 0);
console.log(passed); // true

filter()

Метод filter(), как some() и every(), принимает функцию условия:

filter(callbackFn)
filter(callbackFn, thisArg)

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

callback(element, index, array)

В функцию-коллбек последовательно передается текущий элемент (element), индекс элемента (index) и ссылка на сам перебираемый массив (array). Коллбек возвращает true (или значение, которое соответствует true), если элемент удовлетворяет условию. В ином случае возвращается false.

Опционально в качестве второго параметра в метод filter() можно передать объект, который внутри функции-коллбека можно получить через this

В качестве результата метод filter() возвращает массив тех элементов, которые соответствуют этому условию:

const numbers = [ 1, -12, 8, -4, 25, 42 ];
const filteredNumbers = numbers.filter(n => n > 0);
console.log(filteredNumbers); // [1, 8, 25, 42]

Перебор элементов с помощью forEach()

Метод forEach() осуществляют перебор элементов и применяют к каждому из них определенное действие.

forEach(callbackFn)
forEach(callbackFn, thisArg)

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

callback(element, index, array)

В функцию-коллбек последовательно передается текущий элемент (element), индекс элемента (index) и ссылка на сам перебираемый массив (array).

Опционально в качестве второго параметра в метод forEach() можно передать объект, который внутри функции-коллбека можно получить через this

Например, используем метод forEach() для вычисления квадратов чисел в массиве:

const numbers = [ 1, 2, 3, 4, 5, 6];

numbers.forEach(n => 
	console.log("Квадрат числа", n, "равен", n * n )
);

Метод forEach() в качестве параметра принимает функцию, которая имеет один параметр - текущий перебираемый элемент массива. А в теле функции над этим элементом можно выполнить различные операции.

Консольный вывод программы:

Квадрат числа 1 равен 1
Квадрат числа 2 равен 4
Квадрат числа 3 равен 9
Квадрат числа 4 равен 16
Квадрат числа 5 равен 25
Квадрат числа 6 равен 36

Трансформация массива и map()

Метод map() похож на метод forEach, он принимает те же параметры:

map(callbackFn)
map(callbackFn, thisArg)

Первый параметр - также функция-коллбек, в которую передаются текущий перебираемый элемент, его индекс и ссылка на массив. А второй параметр - значение для this внутри функции-коллбека. Но при этом метод map() возвращает новый массив с результатами операций над элементами массива.

Например, применим метод map к вычислению квадратов чисел массива:

const numbers = [ 1, 2, 3, 4, 5, 6];

const squares = numbers.map(n => n * n);
console.log(squares);	//  [1, 4, 9, 16, 25, 36]

Функция, которая передается в метод map() получает текущий перебираемый элемент, выполняет над ним операции и возвращает некоторое значение. Это значение затем попадает в результирующий массив squares

Поиск в массиве

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

const numbers = [1, 2, 3, 5, 8, 13, 21, 34];

// получаем первый элемент, который больше 10
let found = numbers.find(n => n > 10 );
console.log(found);	// 13

В данном случае получаем первый элемент, который больше 10. Если элемент, соответствующий условию, не найден, то возвращается undefined.

Аналогично метод findLast() возвращает последний элемент, который соответствует условию:

const numbers = [1, 2, 3, 5, 8, 13, 21, 34];

// получаем последний элемент, который меньше 10
let found = numbers.find(n => n < 10 );
console.log(found);	// 8

Метод findIndex также принимает функцию условия, только возвращает индекс первого элемента массива, который соответствует этому условию:

const numbers = [1, 2, 3, 5, 8, 13, 21, 34];

// получаем индекс первого элемента, который больше 10
let foundIndex = numbers.findIndex(n => n > 10 );
console.log(foundIndex);	// 5

Если элемент не найден, то возвращается число -1.

Аналогично метод findLastIndex() возвращает индекс последнего элемента, который соответствует условию:

const numbers = [1, 2, 3, 5, 8, 13, 21, 34];

// получаем индекс последнего элемента,  который меньше 10
let foundIndex = numbers.findIndex(n => n < 10 );
console.log(foundIndex);	// 4

Метод flat и преобразование массива

Метод flat() упрощает массив с учетом указанной вложенности элементов:

const people = ["Tom", "Bob", ["Alice", "Kate", ["Sam", "Ann"]]];
const flattenPeople = people.flat();
console.log(flattenPeople); // ["Tom", "Bob", "Alice", "Kate", ["Sam", "Ann"]]

То есть метод flat() фактически из вложенных массивов переводит элементы во внешний массив самого верхнего уровня. Однако мы видим, что элементы массива второго уровня вложенности перешли в массив первого уровня вложенности, но тем не менее по-прежнему находятся во вложенном массиве. Дело в том, что метод flat() по умолчанию применяется только к вложенным массивам первого уровня вложенности. Но мы можем передать в метод уровень вложености:

const people = ["Tom", "Bob", ["Alice", "Kate", ["Sam", "Ann"]]];
const flattenPeople = people.flat(2);
console.log(flattenPeople); // ["Tom", "Bob", "Alice", "Kate", "Sam", "Ann"]

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

const people = ["Tom", "Bob", ["Alice", "Kate", ["Sam", "Ann"]]];
const flattenPeople = people.flat(Infinity);
console.log(flattenPeople); // ["Tom", "Bob", "Alice", "Kate", "Sam", "Ann"]

with

Иногда необходимо изменить элемент массива, но при этом также сохранить старое состояние массива. Метод with() автоматически создает копию старого массива, изменяет в ней элемент и возвращает новый массив с измененным элементом:

const people = ["Tom", "Bob", "Sam"];
const modified = people.with(0, "Tomas");	// изменяем "Tom" на "Tomas"
console.log(people); 	// ["Tom", "Bob", "Sam"] - начальный массив не изменился
console.log(modified);	// ["Tomas", "Bob", "Sam"] - изменилась копия

reduce

Метод reduce позволяет свести все значения массива в одно значение, которое возвращается из метода. В качестве параметра метод принимает функцию с 4 параметрами:

function (prev,current, curIndex, array){ .... }

Параметры:

  1. prev: предыдущий элемент (в начале - самый первый элемент)

  2. current: текущий элемент (в начале - второй элемент)

  3. curIndex: индекс текущего элемента

  4. array: массив, для которого вызывается функция

Применим метод reduce() для нахождения суммы массива чисел:

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((prev,current) => prev +=current);
console.log(sum);   // 15

В данном случае в метод reduce() передается функция (prev,current) => prev +=current, которая складывает предыдущий элемент с текущим и возвращает их сумму.

Другая форма метода reduce принимает два параметра. Второй параметр - начальное значение, с которого начинается отсчет:

const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((prev,current) => prev +current, 10);
console.log(sum);   // 25

В данном случае начальное значение prev будет равно 10.

Если метод reduce просматривает элементы массива с начала (слева направо), то метод reduceRight() делает это в обратном порядке - справо налево:

const numbers = [1, 2, 3, 4, 5];
const reduced1 = numbers.reduce((prev,current) => prev +=current.toString());
console.log(reduced1);   // 12345
const reduced2 = numbers.reduceRight((prev,current) => prev +=current.toString());
console.log(reduced2);   // 54321

Комбинация методов

При необходимости мы можем объединить несколько операций в цепочку методов. Например, у нас есть массив пользователей:

function Person(name, age){
        this.name = name;
        this.age = age;
}
const people = [
        new Person("Tom", 38), new Person("Kate", 31), 
        new Person("Bob", 42), new Person("Alice", 34), 
        new Person("Sam", 25)
    ];

Выведем из массива people имена всех пользователей, у которых возраст больше 33:

const isAgeMoreThan33 = (p)=>p.age > 33;
const getPersonName = (p)=>p.name;
const printPersonName = (p)=>console.log(p);
 // получаем из Person строку с именем
const view = people
                .filter(isAgeMoreThan33)
                .map(getPersonName)
                .forEach(printPersonName);
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850