Вчера был сборник того, что я делал в дни 1 и 2, с дополнительным бонусом в виде изучения переменных CSS. Конечный продукт? Редактор изображений, да, все еще так его называют. Однако сегодня все будет по-другому, поскольку мы будем работать с массивами и различными методами, которые мы можем использовать.

Проверьте все остальные дни в моем оглавлении!

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

Если вы еще не заметили, я часто ссылаюсь на MDN (Mozilla Developer Network), когда дело касается JavaScript или просто Интернета в целом, потому что у них есть потрясающая библиотека информации, которая хорошо написана и проста для понимания. . Эта статья не будет исключением :)

Array.prototype.filter ()

Метод filter() перебирает массив для создания нового массива на основе теста, который вы пишете внутри функции обратного вызова.

const newArray = array.filter(callback())

В видео Уэса нам дается Массив изобретателей, представленных как Объекты. У каждого объекта есть имя, фамилия, год рождения изобретателя и год его смерти. Цель состоит в том, чтобы отфильтровать тех, кто родился в 1500-х годах.

const fifteen = inventors.filter(function(inventor) {
  if(inventor.year >= 1500 && inventor.year < 1600) {
    return true;
  }
});

Вот что происходит с методом filter():

  1. Мы передаем методу функцию обратного вызова, которая принимает один аргумент: единственного изобретателя. Функция будет вызываться для каждого изобретателя.
  2. Затем мы проверяем, родился ли изобретатель в 1500-х годах, и возвращаем true, если это так.
  3. В новом Array const fifteen теперь есть все изобретатели, вернувшие true.

Функцию обратного вызова также можно записать, как и следовало ожидать, как стрелочную функцию с неявным возвратом:

const fifteen = inventors.filter(inventor => (
   inventor.year >= 1500 && inventor.year < 1600
));

Если вы хотите узнать больше о методе filter(), загляните в MDN. Я думаю, что важно знать, что filter() не изменяет массив, на который вы его вызываете. Вместо этого он создает новый массив.

Array.prototype.map ()

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

const newArray = array.map(callback())

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

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

const fullNames = inventors.map(inventor => (
    `${inventor.first} ${inventor.last}`
));

Вот что происходит:

  1. Как и filter(), мы передаем функцию обратного вызова, которая принимает в качестве аргумента изобретателя. Функция будет вызываться для каждого изобретателя.
  2. Затем мы неявно возвращаем литерал шаблона с именем и фамилией изобретателя, разделенными пробелом.
  3. Новый массив const fullNames теперь содержит все полные имена.

Если вы хотите узнать больше о методе map(), загляните в MDN.

Array.prototype.sort ()

С помощью метода sort() мы можем, как вы могли догадаться по названию, отсортировать массив. Метод принимает функцию обратного вызова, которая принимает два аргумента, которые вы сравните, чтобы понять, как их отсортировать. Затем вы придумываете условие, которое возвращает 1 или -1. При возврате 1 аргумент перемещается вверх в новом массиве, а при возврате -1 аргумент перемещается вниз в новом массиве. Давайте сначала посмотрим на реальный метод:

const newArray = array.sort(callback(a, b))

На этот раз мы хотим отсортировать изобретателей по дате их рождения. Таким образом, самый старший будет наверху, а самый младший - внизу:

const ordered = inventors.sort(function(a, b) {
  if(a.year > b.year) {
    return 1;
  } else {
    return -1;
  }
});

Вот что происходит:

  1. Так же, как filter() и map(), мы передаем функцию обратного вызова, но на этот раз функция принимает два аргумента, которые мы просто вызываем a и b. Метод передаст функцию двум изобретателям для сравнения, пока не будет произведена сортировка.
  2. Мы сравниваем аргументы, используя оператор if, который просто проверяет, больше ли год, в котором родился a, чем год b, и если это так, он вернет 1, таким образом перемещая этого изобретателя вверх в массиве. Если это не так, он вернет -1, перемещая изобретателя вниз в массиве.
  3. Новый массив const ordered теперь содержит список изобретателей, отсортированный по году их рождения.

Если вам нравятся однострочные методы, очень здорово использовать тернарный оператор. Это ярлык для оператора if, который выглядит так:

condition ? expr1 : expr2

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

if(condition) {
  expr1
} else {
  expr2
}

Таким образом, если условие true, оно будет выполняться ?, если нет, оно будет выполнено :.

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

const ordered = inventors.sort((a, b) => a.year > b.year ? 1 : -1);

Довольно круто, правда?

Если вы хотите узнать больше о методе sort(), загляните в MDN.

Array.prototype.reduce ()

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

for (var i, i < 10, i++) {
  console.log(i)
};

С его помощью вы могли делать всевозможные классные вещи, например, вычислять сумму всех чисел внутри массива:

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

Когда цикл завершится, общее количество будет 15, и вы будете счастливы, потому что кто захочет заниматься математикой в ​​уме, верно? Однако проблема с этим подходом заключалась в том, что мне внезапно пришлось делать и изучать все эти дополнительные вещи, такие как обозначение скобок с помощью переменной? Какие?! Это меня на время облажало, и я понятия не имел, что делаю.

Сейчас, оглядываясь назад, я не понимаю, что было так сложно, но задним числом все легко.

Хорошо, вернемся к методу reduce(). Видите ли, у истории есть цель, потому что метод - это, по сути, for цикл, в котором вы можете создать итог на основе выражения, используя все элементы в вашем массиве. Вот как это выглядит:

const newArray = array.reduce(callback(), inititalValue)

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

Итак, используя наших изобретателей в последний раз, мы теперь хотим знать, сколько лет прожили все изобретатели вместе взятые. Вот как мы это делаем:

const totalYears = inventors.reduce((total, inventor) => {
  return total + (inventor.passed - inventor.year);
}, 0);

Вот что происходит:

  1. Как и другие методы, мы передаем функцию обратного вызова, и, как и sort(), этот метод принимает два аргумента: итоговое значение и следующий элемент, который будет использоваться в цикле (который был var i в нашем примере цикла for). Теперь вот почему важно начальное значение. Если обратный вызов вызывается в первый раз, итоговая сумма еще не используется. Вместо этого в качестве первой суммы будет использовано начальное значение.
  2. Затем мы делаем небольшой расчет, чтобы выяснить, как долго прожил конкретный изобретатель, и добавляем его прожитые годы к общему количеству лет, прожитых всеми изобретателями.
  3. Когда цикл закончился, у нас теперь есть переменная const totalYears, которая содержит суммарные годы, прожитые изобретателями.

Сейчас мы используем явный возврат, но мы также можем использовать неявный возврат, например:

const totalYears = inventors.reduce((total, inventor) => (
  total + (inventor.passed - inventor.year)
), 0);

Если вы хотите узнать больше о методе reduce(), загляните в MDN.

TIL (Сегодня я узнал)

  • Мы можем делать аккуратные и полезные oneliners, используя стрелочные функции
  • map() и sort() всегда возвращают одинаковое количество товаров
  • "Аккумулятор" - это просто модное слово для "всего" в reduce() методе
  • Начальное значение очень важно в reduce() методе
  • Как 1 и -1 работают в методе sort()

Уф, это было долго. Я знаю, что для тех, кто дочитает до конца, нужно усвоить много информации. Если честно, написать эту статью было более утомительно, чем выполнить упражнение. Удивительная вещь; Поскольку я пишу эти статьи, я также исследую пару дополнительных вещей, чтобы убедиться, что то, что я пишу, максимально понятно. Так что, помимо видео, я могу определенно сказать, что понимаю, как работают эти методы сейчас!

Весь мой код можно найти на GitHub.

Уэс замечательный учитель. Если вы хотите лучше освоить Javascript, пройдите его бесплатный курс на javascript30.com.

Спасибо за чтение и до следующего раза!