Массивы и циклы

для Epic Skills

Массивы и циклы

Чё, чё, это чё? Кто, кто это сделал?

В предыдущих сериях: массивы

Массив — это коллекция значений
В элементах массива могут содержаться значения любых типов
Массивы нумеруются с нуля
Элементы массива можно получить по числовому ключу
var animals = ["Котик", "Енот", "Лиса"];
alert( animals[0] ); // Котик

В предыдущих сериях: циклы

Цикл нужен для обхода элементов массива
Цикл while выполняется, пока переданное условие верно
var cats = 2; while( cats <= 5 ) cats++

Цикл for задаётся тремя выражениями: начало цикла, условие и шаг
Пока условие выполняется, цикл выполненяет своего содержимого
Доступ к элементам массива в цикле — через квадратные скобки arr[i], где i - номер итерации

Многомерные массивы

Это когда массивы в массиве

var groups = [["Пётр", "Ада"],["Ян", "Маша", "Нат"]];
alert(groups[0]);

Методы перебора массивов

Перебор: forEach

Тот же for, только принимает функцию и даёт ей итерируемый объект

var tutors = ["Тим", "Андрей"];
tutors.forEach(function(item, i, arr) {
  alert( i + ": " + item + " (массив:" + arr + ")" );
});

Перебор: forEach с выносом функции

var tutors = ["Тим", "Андрей"];
function getTutors(item, i, arr) {
  alert( i + ": " + item + " (массив:" + arr + ")" );
}
tutors.forEach(getTutors);

Фильтрация: filter

Когда нужно взять только часть массива. Создаётся новый массив.
var students = ["Алексей Петров", "Надежда Василькова", "Алексей Николаев"];
function findAlex(student, i, arr) {
  return student.split(' ')[0] === "Алексей"
}
alert(students.filter(findAlex));

Трансформация: map

Когда нужен новый массив, данные в котором опираются на имеющийся
var groups = [["Пётр", "Ада"],["Ян", "Маша", "Нат"]];
function countStudents(group, i, arr) {
  return group.length
}
alert(groups.map(countStudents));

Проверка массива: every/some

Когда нужно знать, что все элементы массива чему-то соответствуют
var students = ["Пётр 1", "Николай 2", "Костя"];
function findKings(student, i, arr) {
  var secondName = student.split(' ')[1]
  return secondName && !isNaN(secondName)
}
alert(students.some(findKings));

Длина массива: length

Можно получить количество элементов массива: arr.length
Это количество можно присвоить: arr.length = 100;
Тогда массив может обрезаться или наполниться пустыми элементами
Важно понимать: длина массива равна последнему элементу + 1 var arr = [];
arr[100] = true;
alert(arr.length); // 101

Массивы с дырами

Можно создать массив с пропущенными элементами.
Тогда пропущенные будут undefined

var arr = [];
arr[0] = 0;
arr[10] = 10;
alert(arr);

Методы работы с очередью

Конец массива: pop/push

pop удаляет последний элемент массива
push добавляет элемент в конец массива

var group1 = ["Пётр 1", "Николай 2"];
var group2 = ["Сталин", "Ленин"];
var exchangeStudent = group1.pop()
group2.push(exchangeStudent)

Начало массива: shift/unshift

Та же история, что с pop и push, только в начале массива

var vkCEO = ["Дуров", "Добродеев", "Рогозов"];
var removedCEO = vkCEO.shift()
var telegramCEO = [];
telegramCEO.unshift(removedCEO)

Функции shift и unshift — медленные! Избегайте их!

Методы изменения массивов

Разделение и склейка: split/join

join нужен, чтобы соединить элементы массива строкой:
["Андрей", "Антон", "Кирилл"].join(', '); // "Андрей, Антон, Кирилл"

split — для разделения строки на элементы массива:
"Андрей, Антон, Кирилл".split(', '); // ["Андрей","Антон","Кирилл"]

Лайфхаки split

Разделение с обрезкой: Передаём в split вторым аргументом число для обрезки нового массива до этого количества элементов
"Андрей, Антон, Кирилл".split(', ', 2);
// ["Андрей","Антон"]

Разделить можно не только массив, но и строку:
"Андрей".split(''); // ["А", "н", "д", "р", "е", "й"]

Удаление из массива: delete

Можно удалить любой элемент массива

var arr = ["Все", "любят", "котиков"];

delete arr[2]; // ["Все", "любят", ]

Части массивов: slice

Метод slice(start, end) позволяет взять элементы массива, начиная со start, заканчивая элементом до end

var arr = ["Почему", "надо", "любить", "котиков"]; var arr2 = arr.slice(1, 3); // ["надо, "любить"]

Можно отсчитывать элементы с конца массива
var arr3 = arr.slice(-2); // ["любить, "котиков"]

Нарезка массивов: splice

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

var arr = ["Я", "изучаю", "JavaScript"]; arr.splice(1, 1); // начиная с позиции 1, удалить 1 элемент alert( arr ); // осталось ["Я", "JavaScript"]

Нарезка массивов: splice

Пример со вставкой новых элементов вместо удалённых

var arr = ["Я", "сейчас", "изучаю", "JavaScript"];
arr.splice(0, 3, "Мы", "изучаем") // удалить 3 первых элемента и добавить другие вместо них
alert( arr ) // теперь ["Мы", "изучаем", "JavaScript"]

Вставка без удаления: splice

Можно вставить в любую позицию массива новые элементы без удаления старых

var arr = ["Я", "изучаю", "JavaScript"];
arr.splice(2, 0, "сложный", "язык");
alert( arr ); // "Я", "изучаю", "сложный", "язык", "JavaScript"

Сортировка массива: sort

Можно отсортировать элементы массива в алфавитном порядке

var arr = ["Т", "Ё", "П", "С", "Р"].sort()
// ["Ё", "П", "Р", "С", "Т"]

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

var arr = [ 1, 2, 15 ].sort();
// [ 1, 15, 2 ]

Сортировка массива по своим правилам

Можно отсортировать элементы массива как вам угодно
Передайте функцию, возвращающую положительное число для повышения рейтинга в сортировке и отрицательное для понижения
function compareNum(a, b) {
  if (a > b) return 1;
  if (a < b) return -1;
}
var arr = [ 1, 15, 2 ].sort(compareNum); // 1, 2, 15

Сортировка массива по своим правилам

Можно и так

function compareNum(a, b) {
  return a - b;
}
var arr = [ 1, 15, 2 ].sort(compareNum); // 1, 2, 15

Обращение порядка: reverse

Если нужно полностью зеркально поменять порядок элементов в массиве, это можно сделать функцией reverse

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

Склейка массивов: concat

Можно склеивать массивы конкатом

[1, 2, 3].concat([6, 7, 9], 20, 50)
// [1, 2, 3, 6, 7, 9, 20, 50]

Важно понимать! concat создаёт новый массив!

indexOf, lastIndexOf

indexOf нужен, чтобы узнать позицию элемента в массиве

[3, 0, 8].indexOf(0) // 1

Но ещё чаще его используют для определения наличия элемента в массиве. Пишут это в проверках вот так:

if([3, 8].indexOf(0) === -1) {
// сделать что-нибудь, если элемента нет в массиве
}

Вопросы?