Для сегодняшнего алгоритма мы собираемся создать функцию под названием miniMaxSum. В этой функции вам предоставляется массив из пяти целых чисел, и цель состоит в том, чтобы вывести минимальное и максимальное значения, которые можно вычислить при суммировании четырех из пяти целых чисел в массиве.
Вот пример. Давайте создадим массив с именем arr:
let arr = [1, 2, 3, 4, 5]
Если бы мы визуально перебирали массив, мы бы суммировали оставшиеся четыре числа, исключая номер, на котором сейчас находится цикл.
Цикл переходит к первому числу, мы исключим число 1 и просуммируем оставшиеся четыре числа: 2 + 3 + 4 + 5 = 14.
Цикл переходит ко второму числу, мы исключим число 2 и просуммируем оставшиеся четыре числа: 1 + 3 + 4 + 5 = 13.
Цикл переходит к третьему числу, мы исключим число 3 и просуммируем оставшиеся четыре числа: 1 + 2 + 4 + 5 = 12.
Цикл переходит к четвертому числу, мы исключим число 4 и просуммируем оставшиеся четыре числа: 1 + 2 + 3 + 5 = 11.
Цикл переходит к окончательному числу, мы исключим число 5 и просуммируем оставшиеся четыре числа: 1 + 2 + 3 + 4 = 10.
Из всех сумм 14 является максимальным, а 10 - нашим минимальным, поэтому наша функция выведет эти два числа в одну строку, разделенную пробелом:
10 14
Теперь мы закончили с нашим длинным объяснением, давайте превратим его в код.
Создаем наши переменные:
let totals = []; const reducer = (accumulator, currentValue) => accumulator + currentValue;
Переменная totals соберет все наши суммы и поместит каждую сумму в массив.
Переменная reducer мы объясним позже. Это потребует использования метода Array.reduce () для сложения четырех чисел, чтобы получить нашу сумму.
Сначала мы перебираем наш массив с помощью цикла for:
for (let i = 0; i < arr.length; i++) { let filtered = arr.filter(function(value, index, arr) { return i !== index; }); totals.push(filtered.reduce(reducer)); }
В первой строке в нашем блоке цикла for мы будем использовать метод .filter (), чтобы избавиться от определенных значений в массиве. Что делает метод фильтра, так это то, что он использует метод обратного вызова (функция, выполняющая другую функцию после ее завершения), и по мере того, как метод фильтра выполняет итерацию по каждому элементу массива, он передает три значения в обратный вызов: текущее значение, индекс массива и сам массив. Когда он будет перебирать это конкретное значение массива, обратный вызов вернет либо истину, либо ложь в зависимости от вашего оператора return. Значения, возвращающие истину, добавляются к отфильтрованному массиву.
Когда мы перебираем массив, мы хотим вычислить все элементы в массиве, кроме текущего повторяемого значения.
Что мы делаем, так это используем метод filter, чтобы отфильтровать значение, равное текущему элементу, индексируемому в цикле for. Например, если цикл for в настоящее время находится под вторым числом, мы хотим, чтобы метод фильтрации отфильтровал все числа, у которых индекс не равен 1.
Метод фильтрации не затрагивает и не изменяет исходный массив. Это важно, поэтому у нас всегда есть исходный массив для фильтрации на время цикла for.
Следующая строка:
totals.push(filtered.reduce(reducer));
После того, как метод filter выведет наш массив из четырех значений, мы сложим их вместе с помощью метода reduce.
Что делает метод reduce, так это выполняет функцию редуктора для каждого элемента массива. Это сокращает наш массив до одного значения. Давайте вернемся к тому месту, где мы перечислили наши переменные, и объясним, что делает наша переменная-редуктор:
const reducer = (accumulator, currentValue) => accumulator + currentValue;
Следует отметить, что приведенное выше утверждение эквивалентно написанию:
const reducer = function(accumulator, currentValue){ return accumulator + currentValue; }
Вверху используются стрелочные функции, что является другим способом (и сокращенным) для написания функции.
Метод reduce принимает один обязательный параметр - reducer. Наша функция-редуктор принимает два параметра: аккумулятор и текущее значение. У метода reduce также есть необязательный параметр с именем initialValue, но мы его опустим. Аккумулятор будет равен первому значению в массиве, а текущее значение будет равно второму.
Возвращаясь к нашему примеру вверху с [1, 2, 3, 4, 5], мы увидим связь между currentValue и аккумулятором:
// 2 is the current value. accumulator value updated to 3 1 + 2 = 3 // 3 is the current value. accumulator value updated to 6 3 + 3 = 6 // 4 is the current value. accumulator value updated to 10 6 + 4 = 10 // ... and so on
Каждый раз, когда текущее значение добавляется в аккумулятор, аккумулятор обновляется до тех пор, пока массив не будет завершен, и не будет возвращено окончательное значение аккумулятора.
Вернувшись к циклу for, мы помещаем это значение суммы в массив.
По завершении цикла мы используем методы Math.max () и Math.min () для вычисления максимального и минимального значений в нашем массиве totals и их распечатки.
console.log(Math.min(...totals) + " " + Math.max(...totals));
Вот остальная часть нашего кода:
function miniMaxSum(arr) { let totals = []; const reducer = (accumulator, currentValue) => accumulator + currentValue; for (let i = 0; i < arr.length; i++) { let filtered = arr.filter(function(value, index, arr) { return i !== index; }); totals.push(filtered.reduce(reducer)); } console.log(Math.min(...totals) + " " + Math.max(...totals)); }
Вот еще несколько алгоритмов JavaScript, которые вы можете проверить: