Для сегодняшнего алгоритма мы собираемся создать функцию под названием 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, которые вы можете проверить: