javascript 1.8.4 Массивы. Проверка

Array.isArray

Массивы не образуют отдельный тип языка. Они основаны на объектах.

Поэтому typeof не может отличить простой объект от массива:

alert(typeof {}); // object
alert(typeof []); // тоже object

…Но массивы используются настолько часто, что для этого придумали специальный метод: Array.isArray(value). Он возвращает true, если value массив, и false, если нет.

alert(Array.isArray({})); // false

alert(Array.isArray([])); // true

Большинство методов поддерживают «thisArg»

Почти все методы массива, которые вызывают функции – такие как findfiltermap, за исключением метода sort, принимают необязательный параметр thisArg.

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

Вот полный синтаксис этих методов:

arr.find(func, thisArg);
arr.filter(func, thisArg);
arr.map(func, thisArg);
// ...
// thisArg - это необязательный последний аргумент

Значение параметра thisArg становится this для func.

Например, вот тут мы используем метод объекта army как фильтр, и thisArg передаёт ему контекст:

let army = {
  minAge: 18,
  maxAge: 27,
  canJoin(user) {
    return user.age >= this.minAge && user.age < this.maxAge;
  }
};

let users = [
  {age: 16},
  {age: 20},
  {age: 23},
  {age: 30}
];

// найти пользователей, для которых army.canJoin возвращает true
let soldiers = users.filter(army.canJoin, army);

alert(soldiers.length); // 2
alert(soldiers[0].age); // 20
alert(soldiers[1].age); // 23

Если бы мы в примере выше использовали просто users.filter(army.canJoin), то вызов army.canJoin был бы в режиме отдельной функции, с this=undefined. Это тут же привело бы к ошибке.

Вызов users.filter(army.canJoin, army) можно заменить на users.filter(user => army.canJoin(user)), который делает то же самое. Последняя запись используется даже чаще, так как функция-стрелка более наглядна.

Итого

Шпаргалка по методам массива:

  • Для добавления/удаления элементов:
    • push (...items) – добавляет элементы в конец,
    • pop() – извлекает элемент с конца,
    • shift() – извлекает элемент с начала,
    • unshift(...items) – добавляет элементы в начало.
    • splice(pos, deleteCount, ...items) – начиная с индекса pos, удаляет deleteCount элементов и вставляет items.
    • slice(start, end) – создаёт новый массив, копируя в него элементы с позиции start до end (не включая end).
    • concat(...items) – возвращает новый массив: копирует все члены текущего массива и добавляет к нему items. Если какой-то из items является массивом, тогда берутся его элементы.
  • Для поиска среди элементов:
    • indexOf/lastIndexOf(item, pos) – ищет item, начиная с позиции pos, и возвращает его индекс или -1, если ничего не найдено.
    • includes(value) – возвращает true, если в массиве имеется элемент value, в противном случае false.
    • find/filter(func) – фильтрует элементы через функцию и отдаёт первое/все значения, при прохождении которых через функцию возвращается true.
    • findIndex похож на find, но возвращает индекс вместо значения.
  • Для перебора элементов:
    • forEach(func) – вызывает func для каждого элемента. Ничего не возвращает.
  • Для преобразования массива:
    • map(func) – создаёт новый массив из результатов вызова func для каждого элемента.
    • sort(func) – сортирует массив «на месте», а потом возвращает его.
    • reverse() – «на месте» меняет порядок следования элементов на противоположный и возвращает изменённый массив.
    • split/join – преобразует строку в массив и обратно.
    • reduce(func, initial) – вычисляет одно значение на основе всего массива, вызывая func для каждого элемента и передавая промежуточный результат между вызовами.
  • Дополнительно:
    • Array.isArray(arr) проверяет, является ли arr массивом.

Обратите внимание, что методы sortreverse и splice изменяют исходный массив.

Изученных нами методов достаточно в 99% случаев, но существуют и другие.

  • arr.some(fn)/arr.every(fn) проверяет массив.Функция fn вызывается для каждого элемента массива аналогично map. Если какие-либо/все результаты вызовов являются true, то метод возвращает true, иначе false.
  • arr.fill(value, start, end) – заполняет массив повторяющимися value, начиная с индекса start до end.
  • arr.copyWithin(target, start, end) – копирует свои элементы, начиная со start и заканчивая end, в собственную позицию target (перезаписывает существующие).

Полный список есть в справочнике MDN.

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

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

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

Практика

Перемешайте массив

важность: 3

Напишите функцию shuffle(array), которая перемешивает (переупорядочивает случайным образом) элементы массива.

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

let arr = [1, 2, 3];

shuffle(arr);
// arr = [3, 2, 1]

shuffle(arr);
// arr = [2, 1, 3]

shuffle(arr);
// arr = [3, 1, 2]
// ...

Все последовательности элементов должны иметь одинаковую вероятность. Например, [1,2,3] может быть переупорядочено как [1,2,3] или [1,3,2], или [3,1,2] и т.д., с равной вероятностью каждого случая.

Переведите текст вида border-left-width в borderLeftWidth

важность: 5

Напишите функцию camelize(str), которая преобразует строки вида «my-short-string» в «myShortString».

То есть дефисы удаляются, а все слова после них получают заглавную букву.

Примеры:

camelize("background-color") == 'backgroundColor';
camelize("list-style-image") == 'listStyleImage';
camelize("-webkit-transition") == 'WebkitTransition';

P.S. Подсказка: используйте split, чтобы разбить строку на массив символов, потом переделайте всё как нужно и методом join соедините обратно.

Фильтрация по диапазону “на месте”

важность: 4

Напишите функцию filterRangeInPlace(arr, a, b), которая принимает массив arr и удаляет из него все значения кроме тех, которые находятся между a и b. То есть, проверка имеет вид a ≤ arr[i] ≤ b.

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

Например:

let arr = [5, 3, 8, 1];

filterRangeInPlace(arr, 1, 4); // удалены числа вне диапазона 1..4

alert( arr ); // [3, 1]

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *