Реализуйте общие редукторы sum, min и max
Агрегатная функция в запросе SQL выполняет вычисление одного или нескольких значений и возвращает одно значение.
COUNT
подсчитывает количество строк.SUM
складывает все значения из данного столбца.MIN
иMAX
возвращают наименьшее и наибольшее значения из указанного столбца.AVG
вычисляет среднее число из всех значений в данном столбце.
Во всех примерах мы будем использовать следующую таблицу.
Articles Title | Views 3 Ways of Invoking a Method | 123 3 Iterables Converted Into Arrays | 88 How to Find Elements in Array | 402 How to Position a Div | 103
Ниже представлен соответствующий массив объектов статьи.
const articles = [ {title: '3 Ways of Invoking a Method', views: 123}, {title: '3 Iterables Converted Into Arrays', views: 88}, {title: 'How to Find Elements in Large Arrays', views: 402}, {title: 'How to Position a Div Element', views: 103} ]
Метод reduce
объединяет все значения из массива в одно значение с помощью функции редуктора. Он выполняет заданную функцию редуктора для каждого элемента массива.
Мы можем писать различные функции-редукторы и вычислять те же агрегаты, что и агрегатные функции, полученные с помощью агрегатных функций в запросах SQL.
Считать
Следующий запрос SQL подсчитывает количество строк в Articles
таблице.
SELECT COUNT(*)
FROM Articles
--4
Чтобы получить количество объектов в массиве, мы можем просто получить доступ к свойству length
.
articles.length
Тем не менее, мы можем написать редуктор, который не считает значения null
или undefined
в массиве. Вычисленное значение увеличивается на каждом шаге, если текущий элемент не равен нулю.
function count(total, article){ return (article != null && article !== undefined) ? total + 1 : total; }
Общее совокупное значение инициализируется 0
. Обратите внимание на второй аргумент, переданный методу reduce
.
const noOfArticles= articles.reduce(count, 0); //4
Сумма
Следующий запрос SQL извлекает общее количество просмотров всех статей в таблице.
SELECT SUM(Views)
FROM Articles
--716
Мы можем вычислить общий вид из массива объектов, используя следующую функцию редуктора. Требуется общее количество просмотров, вычисленное на данный момент, и текущая статья. Он извлекает количество просмотров из статьи и добавляет его к общему количеству.
function sum(total, article){ const {views} = article; return total + views; }
При выполнении этого вычисления мы начинаем с 0
в качестве начальной суммы просмотров.
const total = articles.reduce(sum, 0); //716
Предыдущее решение подходит, оно выполняет необходимые вычисления, но слишком специфично. Давайте попробуем написать более общую функцию, которая принимает имя свойства, используемого для вычисления суммы.
function sum(propName){}
Дело в том, что метод reduce
вызывает функцию редуктора с двумя аргументами. Первый - это агрегированное значение, вычисленное на данный момент, а второй аргумент - это текущий элемент. Метод reduce
не отправляет имя свойства, которое мы хотим принять.
Решение состоит в том, чтобы заставить функцию sum
принимать имя необходимого свойства, а затем возвращать функцию-редуктор, требуемую методом reduce
.
Вот пример.
function sum(propName){ return function(total, obj){ const {[propName]: value} = obj; return total + value; } }
Обратите внимание, как мы динамически извлекаем свойство из объекта в новую переменную с именем value
, используя синтаксис деструктурирующего присваивания.
const {[propName]: value} = obj;
Ниже функция sum
создает функцию редуктора, используемую методом reduce
.
const total = articles.reduce(sum('views'), 0); //716
Функция, принимающая на вход другую функцию или возвращающая функцию, является функцией более высокого порядка. sum
- функция высшего порядка.
Мин.
В следующем запросе SQL используется агрегатная функция MIN
, чтобы показать минимальное количество просмотров в статье.
SELECT MIN(Views) FROM Articles //88
Тот же результат может быть достигнут с помощью редуктора, который берет минимальное количество просмотров, вычисленных на данный момент, и текущий объект статьи. Когда текущая статья имеет меньше просмотров, чем текущий минимум, вычисленный на данный момент, текущее количество просмотров становится новым минимальным значением.
function min(propName){ return function(minimum, obj){ const {[propName]: value} = obj; return value < minimum ? value : minimum; } }
Нам нужно ответить на еще один вопрос. При вычислении сумма 0
была начальным значением. Какое начальное значение при вычислении минимума?
Хороший вариант - использовать количество просмотров из первой статьи в качестве начального минимального значения.
const minum = articles.reduce(min('views'), articles[0].views); //88
Максимум
В приведенном ниже запросе SQL применяется агрегатная функция MAX
, чтобы найти максимальное количество просмотров.
SELECT MAX(Views) FROM Articles
Функция MAX
принимает имя свойства для проверки и возвращает функцию-редуктор. Редуктор получает вычисленное максимальное значение на данный момент и текущий объект. Когда текущий объект имеет количество просмотров больше, чем вычисленное значение, тогда текущее количество просмотров становится новым максимумом. В противном случае возвращается уже вычисленное максимальное значение.
function max(propName){ return function(maximum, obj){ const {[propName]: value} = obj; return value > maximum ? value : maximum; } }
При вызове метода reduce
мы можем начать с 0
как начального максимального количества просмотров.
const total = articles.reduce(max('views'), 0); console.log(total); //402
Средн.
В приведенном ниже запросе вычисляется среднее количество просмотров всех статей с помощью функции AVG
.
SELECT AVG(Views) FROM Articles --179
Среднее значение - это результат разделения суммы всех просмотров по числам или статьям. Мы можем использовать предыдущий редуктор sum
, чтобы вычислить общее количество просмотров, а затем проанализировать его по количеству элементов в массиве.
const total= articles.reduce(sum('views'), 0); const averageViews = total / articles.length; //179
Последние мысли
Агрегатная функция в SQL-запросе позволяет агрегировать значения из нескольких строк в вычисленное значение.
Метод уменьшения массива позволяет агрегировать все элементы массива в одно значение.
Мы можем реализовать функции редуктора и вычислять те же агрегаты, что и агрегаты, полученные с помощью агрегатных функций в запросах SQL.
Спасибо за чтение.
Вы также можете проверить Как найти элементы в больших массивах.