JS Array. Операции с массивами
Объекты в JS удобны для данных, имеющих строчные ключи, но не подходят для создания блока элементов, упорядоченных по номерам. Это обусловлено отсутствием методов изменения порядка единиц, включенных в блок, добавления или изъятия новых элементов с коррекцией нумерации. Создавать упорядоченные списки элементов и манипулировать ими можно, используя массивы.
Внутреннее устройство массива
Массивы JS представляют собой наборы элементов, каждый из которых имеет порядковый номер (индекс). Элементы могут иметь любой тип данных. Можно создать и неоднородный массив, включающий в себя компоненты разных типов. Элементу, идущему первым, присваивается номер 0.
У последующих частей массива последовательность индексов выглядит как возрастающий ряд целых чисел, начинающийся с единицы. Возможно и применение в роли индексов отрицательных чисел – тогда они превращаются в строчки, представляемые как названия свойств.
Жесткая заданность числа компонентов массивам не свойственна: напротив, из них можно убирать элементы или вставлять новые. Распределение памяти заново при этом не требуется.
Чем массив отличается от объекта
Массив представляет собой разновидность объекта, поэтому генерализованные свойства второго (к примеру, возможность копирования или изменения по ссылке) применимы и к первому. Синтаксис Arr[1], описывающий индекс элемента, является вариацией записи доступа к объекту по ключу obj[key].
При этом данный вид объектов обладает и рядом новых характеристик, например, свойством, описывающим длину, а также методами, заточенными под манипуляцию с нумерованными последовательностями данных. При работе с массивами JS (Array) можно создать и вложенную композицию, элементы которой будут представлять собой объекты или массивы.
Во втором варианте массив называется многомерным. Такая конструкция подходит для представления матрицы.
Особенность этой конструкции – способ хранения данных движком JS. Элементы в своей последовательности сохраняются в непрерывной памяти, что ускоряет ход операций с ними.
Но если обращаться с массивом как с простым объектом, все выгоды этой конфигурации перестанут работать: движок замечает некорректное обращение с конструкцией и реагирует соответствующим образом, выключая методы, оптимизирующие работу.
Вот примеры неправильной работы с массивом:
- создание свойства, индекс которого значительно больше числа элементов;
- компоновка списка с большими лакунами: например, сначала задается компонент с индексом 0, затем с индексом 50, а между ними – пустота;
- наполнение списка от большего индекса к меньшему (сначала вводят Arr[50], затем Arr[49] и так далее).
Словом, вводя в Javascript массивы, следует помнить, что данная структура заточена специально под работу с нумерованной совокупностью данных, и использовать их по назначению. В случаях, когда требуется получить произвольные ключи, скорее всего, более подходящим будет простой объект.
Возможно и применение в роли индексов отрицательных чисел – тогда они превращаются в строчки, представляемые как названия свойств.
Как создать массив
Самый короткий и распространенный способ сделать это – воспользоваться записью по схеме «let arr = [];». При этом в квадратных скобках можно указывать первоначальные значения компонентов множества, начиная с имеющего нулевой индекс. Например:
Let cars = [“Mercedes”, “Hyundai”, “Toyota”];
Другая возможная схема – “let arr = new Array();”. Используют ее нечасто из-за более длинной записи. К тому же, если вызвать этим способом множество с одним численным аргументом, будет создано пустое множество с фиксированной длиной. Все входящие в такое множество компоненты будут равны undefined.
Если потребовалось вывести элемент с определенным номером (например, значением индекса, равным 2), используют следующую запись:
Let cars = [“Mercedes”, “Hyundai”, “Toyota”];
Alert( cars[2] );
Выведется название марки Toyota.
Операцию замены компонента, имеющего некоторый индекс, реализуют так:
Cars[2] = “Lada”;
Теперь в этом массиве, содержащим 3 названия марок машин, вместо Toyota будет располагаться Lada.
К уже сформированному множеству можно добавить и дополнительный элемент:
Cars[3] = “Volvo”;
В результате последовательность будет выглядеть так: “Mercedes”, “Hyundai”, “Lada”, “Volvo”.
Длина массива array в Javascript может быть вызвана так:
alert( array.length );
Посредством alert можно и вывести элементы множества на экран с сохранением их последовательности. Например:
Let cars = [“Hyundai”, “Lada”, “Volvo”];
Alert ( cars );
На экран выведется такая запись:
Hyundai, Lada, Volvo
Можно хранить в множестве элементы разных видов, к примеру:
Let array = [ ‘Volvo’, { name: ‘Thomas’ }, true, function() { alert(‘Hello’); } ];
Допустим, стоит цель взять компонент этого массива, имеющий индекс 1, и вывести его свойство. Для этого делается такая запись:
Alert( array[1].name );
В результате на экран выведется имя Thomas.
Под индексом 3 в данном упорядоченном массиве идет функция. Чтобы ее реализовать, делают следующую запись:
Array[3]();
В итоге выведется Hello.
Длина массива
Поскольку начальный компонент всегда имеет цифровой индекс 0, длина массива в JS не будет идентичной значению максимального индекса. Если в нумерации нет пустых мест, то, чтобы найти длину, нужно к последнему числу прибавить единицу.
Если же вызывают в JS length массива array, на экран также выводится число, на единицу большее максимального индекса, но это не обязательно будет длина (т.е. количество элементов). Это в определенных условиях может приводить к специфическим эффектам.
Например, если объявить массив, потом задать элемент с большим числом индекса, а после этого вызывать length, значение последней будет на 1 больше, чем у индекса, хотя элемент, имеющий определенное значение, в массиве может быть всего один (остальные в таком случае будут иметь значение undefined). Вот как это выглядит:
Let cars = [];
Cars[1234] = “Lada”;
Alert( cars.length );
В результате выведется число 1235.
Одна из особенностей параметра length – возможность увеличивать или уменьшать его значение. Укорачивание выборки реализуется так:
Let m = [1, 2, 3, 4, 5];
m.length = 2;
alert( m );
В этом примере массив редуцировали до двух элементов. При выведении обновленной совокупности на монитор останутся лишь первые два числа из 5 (1 и 2). Что же будет, если попробовать вернуть первоначальную длину?
m.length = 5;
alert( m[3] );
Если попробовать отобразить третий элемент новой совокупности, получится значение undefined.
Таким образом, если выборку сначала укоротить, а затем вернуть прежний размер, значения вырезанных элементов восстановить не получится. Если массив требуется опустошить, это легко сделать так: arr.length = 0.
Перебор элементов
Один из классических методов перебрать сгенерированные с помощью Javascript массивы – цикл for, работающий с индексами компонентов. Реализуется он так:
Let herbs = [“parsley”, “sage”, “rosemary”];
For (let I = 0; I < herbs.length; i++) {
Alert( herbs[i] );
}
Практикуется и иной вариант перебора – for..of. Он вызывает лишь значение элемента без его номера, но в ряде ситуаций этого хватает. Кроме того, такая запись более лаконична. Выглядит она так:
Let herbs = [“parsley”, “sage”, “rosemary”];
For (let herb of herbs) {
Alert( herb );
}
Теоретически можно применить и цикл for..in:
Let herbs = [“parsley”, “sage”, “rosemary”];
For (let key in herbs) {
Alert( herbs[key] );
}
При выводе получаем выдачу: parsley, sage, rosemary. Но использование этого цикла не является оптимальным и имеет существенные минусы. Прежде всего, это низкая скорость, в десятки раз уступающая другим вариантам.
Она обусловлена тем, что способ заточен под работу с простыми объектами. Еще один недостаток – выводятся и нецифровые свойства, которые обычно не требуются.
Методы добавления и удаления элементов
Это одни из наиболее часто используемых методов массива JS. Они нужны, например, при реализации очереди – нумерованного набора элементов, для которого возможны операции добавления элемента в конец и удаления его из начала.
При воплощении второй операции происходит сдвиг очереди, в результате которого второй ее компонент становится первым. Оба этих действия могут быть реализованы с помощью методов массива push и shift.
Еще одна структура, где часто задействуются массивы – стек. В ней реализуются такие операции: рор (удаление конечного компонента) и push (позволяет добавить в JS массив последний элемент). Соответственно, как добавление, так и вырезание компонентов производятся из конечной части. В JS можно работать с массивом как по принципу очереди, так и по типу стека.
Чтобы вырезать из структуры последний компонент и вывести его, применяют метод pop:
Let foodherbs = [“thyme”, “garlic”, “ocimum”];
Alert( foodherbs.pop() );
Alert (foodherbs );
В результате в массиве останутся первые два компонента. Для добавления элемента в хвост используют push:
Let foodherbs = [“thyme”, “garlic”];
Foodherbs.push(“ocimum”);
Alert ( foodherbs );
Для работы с началом упорядоченной совокупности в ходу методы shift и unshift. Первый из них вычленяет и выводит первый компонент:
Let medherbs = [“mint”, “leonurus”, “valeriana”];
Alert( medherbs.shift() );
Alert( medherbs );
В примере выше первая строка объявляет группу элементов, вторая удаляет и отображает первый из них, а третья выводит результирующий массив, в котором есть все компоненты, кроме начального.
Чтобы добавить новый пункт в начало, применяют unshift:
Let medherbs = [“leonurus”, “valeriana”];
Medherbs.unshift(“mint”);
Alert( medherbs );
С помощью методов, вводящих новые элементы, можно пополнить совокупность на несколько пунктов за один раз. Пример с фруктами:
Let fruits = [“apple”];
Fruits.push(“kiwi”, “pear”];
Fruits.unshift(“pineapple”, “lemon”);
Alert( fruits );
Другие методы
Чтобы объединить несколько однородных или разнородных массивов, можно использовать метод concat(). Вот пример работы с однородными совокупностями – названиями птиц и насекомых:
Var birds = [“sparrow”, “owl”, “eagle”];
Var insects = [“fly”, “louse”, “mosquito”];
Var creatures = birds.concat(insects);
For(var i=0; I < creatures.length; i++)
Console.log(creatures[i] );
Для разнородных выборок (например, продукты и цены на них) композиция будет выглядеть так:
Var dairy = [“milk”, “kefir”, “cheese”];
Var prices = [30, 40, 90];
Var products = dairy.concat(prices);
Чтобы отсортировать выборку по возрастанию (если значения имеют текстовую форму – по алфавиту), используется метод sort(). Реализуют его так:
Var fruits = [“apples”, “pears”, “pineapples”, “apricots”, “peaches”];
Fruits.sort();
For(var i=0; i <fruits.length; i++);
Console.log(fruits[i] );
В итоге в браузерном окне перечень отобразится так: apples, apricots, peaches, pears, pineapples.
Есть и метод reverse(). Схема его исполнения полностью аналогична предыдущему (меняется только название), а действие заключается в том, что массив инвертируется задом наперед. То есть, если исходная совокупность выглядела как такой порядок чисел: 1 2 3 4 5, то новая будет иметь вид 5 4 3 2 1.