Работа с массивами в JavaScript | OTUS

Работа с массивами в JavaScript

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

Для начала вспомним, что в JavaScript массивы являются нетипизированными, то есть элементы массива могут иметь любой тип, при этом разные элементы в одном и том же массиве иногда имеют разные типы. Мало того, элементы массива в JavaScript бывают объектами либо даже другими массивами — всё это позволяет создавать действительно сложные структуры данных, например, массивы массивов и массивы объектов.

Идём дальше. В языке JavaScript отчёт индексов массивов начинается с нуля, причём для них применяются 32-битные целые числа. Что касается первого элемента массива, то его индекс равен нулю.

В JavaScript массивы являются динамическими, в результате чего они способны уменьшаться и увеличиваться в размерах в случае необходимости. И вообще, в JavaScript отсутствует необходимость объявлять фиксированные размеры массивов в процессе их создания либо повторно распределять память в случае изменения размеров массивов.

Также можно сказать, что в JavaScript массивы являются специализированной формой объектов, а индексы массивов значат больше, чем просто имена свойств, по совпадению являющихся целыми числами.

Но давайте закончим со скучной теорией и перейдём к практике. В JavaScript массив представляет объект Array. При этом существует ряд методов и свойств, позволяющих управлять нашим массивом.

Инициализация массива в JavaScript

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

    var users = new Array();
var people = [];

console.log(users); // Array[0]
console.log(people); // Array[0]

Кроме того, мы можем сразу же инициализировать наш массив некоторым числом элементов:

    var users = new Array("Bill", "Tom", "Alice");
var people = ["Sam", "John", "Kate"];

console.log(users); // ["Bill", "Tom", "Alice"]
console.log(people); // ["John", "Sam", "Kate"]

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

    var users = new Array();
users[1] = "Tom";
users[2] = "Kate";
console.log(users[1]); // "Tom"
console.log(users[0]); // undefined

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

length

Если хотим узнать длину массива в JS, используем свойство length:

    var fruit = new Array();
fruit[0] = "груши";
fruit[1] = "яблоки";
fruit[2] = "сливы";

document.write("В массиве fruit " + fruit.length + " элемента: <br/>");
for(var i=0; i < fruit.length; i++)
    document.write(fruit[i] + "<br/>");

Фактически, длиной нашего массива в JavaScript будет индекс последнего элемента, плюс единица. К примеру:

    var users = new Array(); // в массиве 0 элементов
users[0] = "Kate";
users[1] = "Tom";
users[4] = "Sam";
for(var i=0; i<users.length;i++)
    console.log(users[i]);

В этом случае вывод браузера будет следующим:

Kate
Tom
undefined
undefined
Sam

Вне зависимости от того, что для индексов №№ 2 и 3 мы элементов не добавляли, длиной массива будет число 5, ведь элементы с индексами №№ 2 и 3 будут просто иметь значение undefined.

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

slice()

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

В первом случае мы присваиваем переменной значение другой переменной, хранящей массив:

    var users = ["Tom", "Bob", "Bill"];
console.log(users);     //  ["Tom", "Bob", "Bill"]
var people = users;     //  shallow copy

people[1] = "John";     //  меняем 2-й элемент
console.log(users);     //  ["Tom", "John", "Bill"]

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

Вышеописанное поведение не всегда желательно. К примеру, нам надо, чтобы после копирования переменные указывали на отдельные массивы. Тогда подойдёт глубокое копирование посредством метода slice():

    var users = ["Tom", "Bob", "Bill"];
console.log(users);             //  ["Tom", "Bob", "Bill"]
var people = users.slice();     //  deep copy

people[1] = "John";             //  меняем 2-й элемент
console.log(users);             //  ["Tom", "Bob", "Bill"]
console.log(people);            //  ["Tom", "John", "Bill"]

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

Кроме того, функция slice() даёт возможность копировать часть массива:

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

В функцию slice() мы передаём начальный и конечный индексы, используемые для выборки значений из нашего массива. В таком случае выборка в новый массив начнётся с первого индекса по индекс № 4, не включая его. И, так как индексация массивов в JavaScript начинается с нуля, в новом массиве будут 2-й, 3-й и 4-й элементы.

push()

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

    var fruit = [];
fruit.push("груши");
fruit.push("яблоки");
fruit.push("сливы");
fruit.push("вишни","абрикосы");

document.write("В массиве fruit " + fruit.length + " элемента: <br/>");
document.write(fruit); // груши,яблоки,сливы,вишни,абрикосы

pop()

Такая функция, как pop(), удалит последний элемент из JavaScript-массива:

    var fruit = ["груши", "яблоки", "сливы"];

var lastFruit = fruit.pop(); // из массива извлекается последний элемент
document.write(lastFruit + "<br/>");
document.write("В массиве fruit " + fruit.length + " элемента: <br/>");
for(var i=0; i <fruit.length; i++)
    document.write(fruit[i] + "<br/>");

Итоговый вывод:

сливы
В массиве fruit 2 элемента: 
груши
яблоки

shift()

Теперь рассмотрим функцию shift(). Она может извлекать и удалять 1-й элемент из массива:

    var fruit = ["груши", "яблоки", "сливы"];

var firstFruit = fruit.shift();
document.write(firstFruit + "<br/>");
document.write("В массиве fruit " + fruit.length + " элемента: <br/>");
for(var i=0; i <fruit.length; i++)
    document.write(fruit[i] + "<br/>");

Вывод следующий:

груши
В массиве fruit 2 элемента: 
яблоки
сливы

unshift()

Что касается функции unshift(), то она добавит новый элемент в самое начало массива:

    var fruit = ["груши", "яблоки", "сливы"];
fruit.unshift("апельсины");
document.write(fruit);

Вывод браузера:

апельсины,груши,яблоки,сливы

Удаление элемента по индексу в JavaScript

splice()

Функция splice() удалит элементы с определённого индекса. Вот как выглядит удаление элементов с 3-го индекса:

    var users = ["Tom", "Bob", "Bill", "Alice", "Kate"];
var deleted = users.splice(3);
console.log(deleted);       // [ "Alice", "Kate" ]
console.log(users);         // [ "Tom", "Bob", "Bill" ]

А возвратит удалённые элементы метод slice.

Как видите, удаление идёт с начала массива. Но если передадим отрицательный индекс, удаление начнётся с конца массива. Давайте удалим лишь последний элемент:

    var users = ["Tom", "Bob", "Bill", "Alice", "Kate"];
var deleted = users.splice(-1);
console.log(deleted);       // [ "Kate" ]
console.log(users);         // [ "Tom", "Bob", "Bill", "Alice" ]

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

    var users = ["Tom", "Bob", "Bill", "Alice", "Kate"];
var deleted = users.splice(1,3);
console.log(deleted);       // [ "Bob", "Bill", "Alice" ]
console.log(users);         // [ "Tom", "Kate" ]

Можно вставить новые элементы вместо удаляемых:

    var users = ["Tom", "Bob", "Bill", "Alice", "Kate"];
var deleted = users.splice(1,3, "Ann", "Roy");
console.log(deleted);       // [ "Bob", "Bill", "Alice" ]
console.log(users);         // [ "Tom", "Ann", "Roy", "Kate" ]

Обратите внимание, что мы удалили 3 элемента (с первого по третий индексы), а вместо них вставили только два элемента.

concat()

Метод или функция concat() нужна, чтобы объединять массивы:

    var fruit = ["груши", "яблоки", "сливы"];
var vegetables = ["огурцы", "помидоры", "картошка"];
var products = fruit.concat(vegetables);

for(var i=0; i < products.length; i++)
    document.write(products[i] + "<br/>");

И совсем необязательно объединять лишь однотипные массивы, можно и разнотипные:

    var fruit = ["груши", "яблоки", "сливы"];
var prices = [20, 30, 70];
var products = fruit.concat(prices);

join()

Функцией join() можем объединить в одну строку все элементы массива:

    var fruit = ["груши", "яблоки", "сливы", "абрикосы", "апельсины"];
var fruitString = fruit.join(", ");
document.write(fruitString);

В функцию join() передаётся разделитель между элементами массива. В нашем случае в качестве разделителя используется запятая и пробел (", ").

sort()

Функция sort() позволяет сортировать массив по возрастанию:

    var fruit = ["груши", "яблоки", "сливы", "абрикосы", "пони"];
fruit.sort();

for(var i=0; i < fruit.length; i++)
    document.write(fruit[i] + "<br/>");

В результате элементы будут отсортированы по алфавиту:

абрикосы
груши
пони
сливы
яблоки

reverse()

С помощью reverse() мы перевернём массив задом наперед:

    var fruit = ["груши", "яблоки", "сливы", "абрикосы", "апельсины"];
fruit.reverse();

for(var i=0; i < fruit.length; i++)
    document.write(fruit[i] + "<br/>");

Итог:

апельсины
абрикосы
сливы
яблоки
груши

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

Функции indexOf() и lastIndexOf() вернут индекс 1-го и последнего включения элемента в массиве. К примеру:

    var fruit = ["яблоки", "груши", "огурцы", "яблоки", "груши"];

var firstIndex = fruit.indexOf("яблоки");
var lastIndex = fruit.lastIndexOf("яблоки");
var otherIndex = fruit.indexOf("черешня");
document.write(firstIndex); // 0
document.write(lastIndex);  // 3
document.write(otherIndex); // -1

У firstIndex значение 0, так как первое включение «яблоки» в нашем массиве приходится на индекс 0, последнее — на индекс № 3. Если же элемент в массиве отсутствует, функции indexOf() и lastIndexOf() вернут значение -1.

every()

С помощью every() мы проверим, все ли наши элементы соответствуют какому-нибудь условию:

    var numbers = [ 1, -12, 8, -2, 25, 62 ];
function condition(value, index, array) {
    var result = false;
    if (value > 0) {
        result = true;
    }
    return result;
};
var passed = numbers.every(condition);
document.write(passed); // false

В метод every() в качестве параметра осуществляется передача функции, представляющей условие. Данная функция принимает 3 параметра:

    function condition(value, index, array) {

}

Здесь параметр value представляет перебираемый текущий элемент массива, параметр index представляет индекс данного элемента, а параметр array осуществляет передачу ссылки на массив.

В такой функции можно проверить переданное значение элемента на его соответствие определённому условию. В нашем примере мы проверяем каждый элемент массива на условие, больше ли он нуля. Когда больше, возвращается значение true, так как элемент соответствует условию. Когда меньше, возвращается значение false, т. к. элемент не соответствует нашему условию.

В результате, когда осуществляется вызов метода numbers.every(condition) он выполняет перебор всех элементов нашего массива numbers, а потом поочерёдно передает их в функцию condition. Когда эта функция возвращает значение true для всех элементов, метод every() тоже возвращает true. Когда хоть один элемент условию не соответствует, возвращается false.

some()

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

Здесь some() вернёт true. Но если соответствующих условию элементов в массиве не будет, вернётся false:

    var numbers = [ 1, -12, 8, -2, 25, 62 ];
function condition(value, index, array) {
    var result = false;
    if (value === 8) {
        result = true;
    }
    return result;
};
var passed = numbers.some(condition); // true

filter()

Как some() и every(), метод filter()принимает функцию условия. Но тут возвращается массив элементов, соответствующих условию:

    var numbers = [ 1, -12, 8, -2, 25, 62 ];
function condition(value, index, array) {
    var result = false;
    if (value > 0) {
        result = true;
    }
    return result;
};
var filteredNumbers = numbers.filter(condition);

for(var i=0; i < filteredNumbers.length; i++)
    document.write(filteredNumbers[i] + "<br/>");

Вот результат вывода:

1
8
25
62

forEach() и map()

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

    var numbers = [ 1, 2, 3, 4, 5, 6];
for(var i = 0; i<numbers.length; i++){

    var result = numbers[i] * numbers[i];

    document.write("Квадрат нашего числа " + numbers[i] + " равен " + result + "<br/>");
}

Конструкция может быть упрощена посредством forEach():

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

function square(value, index, array) {

    var result = value * value;
    document.write("Квадрат нашего числа " + value + " равен " + result + "<br/>");
};

numbers.forEach(square);

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

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

Допустим, давайте, применим map к вычислению квадратов чисел нашего массива:

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

function square(value, index, array) {

    return result = value * value;
};

var squareArray = numbers.map(square);
document.write(squareArray);

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

Не пропустите новые полезные статьи!

Спасибо за подписку!

Мы отправили вам письмо для подтверждения вашего email.
С уважением, OTUS!

Автор
0 комментариев
Для комментирования необходимо авторизоваться
Популярное
Сегодня тут пусто