Вопрос по аккумулятору JavaScript .reduce - PullRequest
1 голос
/ 30 апреля 2020

Я работал над этой проблемой, чтобы создать функцию, используя метод Reduce, который получит максимальное число в массиве.

Ответ преподавателя:

const numbers = [1, 2, 3, 4, 4, 5, 1, 3, 4];
const max = getMax(numbers);
console.log(max);
function getMax(array) {
   if (array.length === 0) return undefined;
   return array.reduce((accumulator, current) => {
       return (accumulator > current) ? accumulator : current
}); 

Я пробовал что-то вроде этого:

 return array.reduce((accumulator, current) => {
    if (accumulator < current)
        console.log(accumulator, current);
        return accumulator = current;
});   

Я добавил console.log (аккумулятор, ток), потому что я хотел видеть что происходит с моим кодом. Журнал показывает следующее:

console.log моего кода

1 2
2 3
3 4
4 5
1 3
3 4
4

Вопрос 1. Я хотел бы знать, почему моя функция не выдает правильный вывод (вернуло 4, неправильный вывод 5). Разве «аккумулятор» не должен оставаться 5, если ему присвоено значение 5 во время l oop?

Вопрос 2. Почему мне нужно возвращать (или добавлять возврат перед) массив в функции, когда под оператором if уже есть возврат?

Ответы [ 2 ]

1 голос
/ 30 апреля 2020

Вы не использовали { ... } после вашего if заявления, поэтому только первая строка console.log(...) происходит при выполнении условия. Строка accumlator = current всегда происходит для каждой итерации. Вы должны использовать return при использовании императивного стиля if оператор . Однако вы можете пропустить return при использовании функционального стиля выражений , ie (accumulator, current) => accumulator < current ? current : accumulator, который говорит "если аккумулятор меньше тока, возвратный ток, иначе возвратный аккумулятор" .

Рассмотрим эту разложенную программу. Когда мы видим max как независимую функцию, это помогает нам точно определить тип функции, которую ожидает reduce -

const max = (a = 0, b = 0) =>
  a < b               // if a is less than b
    ? b               // return b
    : a               // otherwise return a
 
const getMax = (numbers = []) =>
  numbers.length === 0          // if numbers.length is zero
    ? undefined                 // return undefined
    : numbers.reduce(max)       // otherwise return reduction

console.log(getMax([1, 2, 3, 4, 4, 5, 1, 3, 4]))
// 5

console.log(getMax([]))
// undefined

console.log(getMax())
// undefined

Мы видим, что reduce производит следующие вычисления -

// given
[1, 2, 3, 4, 4, 5, 1, 3, 4]

// starting with the first two
r = max(1, 2)

// then the next number
r = max(r, 3)

// then the next number
r = max(r, 4)

// then the next number
r = max(r, 4)

Или без промежуточных r = ... -

max(max(max(max(max(max(max(max(1, 2), 3), 4), 4), 5), 1), 3), 4)

Мы могли бы написать getMax без reduce, если бы мы хотели -

const max = (a = 0, b = 0) =>
  a < b
    ? b
    : a
 
const getMax = (numbers = []) =>
  numbers.length === 0 // without any numbers,
    ? undefined        // there can be no max.
: numbers.length === 1 // if we only have one,
    ? numbers[0]       // we already know max.
    : max(numbers[0], getMax(numbers.slice(1))) // else

console.log(getMax([1, 2, 3, 4, 4, 5, 1, 3, 4]))
// 5

console.log(getMax([]))
// undefined

console.log(getMax())
// undefined

Или, может быть, вы еще не научились slice. Вы можете использовать индекс массива, i, для перехода по вашему массиву -

const max = (a = 0, b = 0) =>
  a < b
    ? b
    : a
 
const getMax = (numbers = [], i = 0) =>
  numbers.length === 0    // without any numbers,
    ? undefined           // there can be no max.
: i + 1 >= numbers.length // if the next i is not in bounds,
    ? numbers[i]          // this is the last number
    : max(numbers[i], getMax(numbers, i + 1)) // else

console.log(getMax([1, 2, 3, 4, 4, 5, 1, 3, 4]))
// 5

console.log(getMax([]))
// undefined

console.log(getMax())
// undefined

Можно также использовать назначение деструктурирования -

const max = (a = 0, b = 0) =>
  a < b
    ? b
    : a
 
const getMax = ([ num, ...more ] = []) =>
  more.length === 0
    ? num
    : max(num, getMax(more))
    
console.log(getMax([1, 2, 3, 4, 4, 5, 1, 3, 4]))
// 5

console.log(getMax([]))
// undefined

console.log(getMax())
// undefined

Это может показать вам, как вы можете изобрести свой собственный reduce -

const max = (a = 0, b = 0) =>
  a < b
    ? b
    : a
 
const reduce = (f, a = [], i = 0) =>
  a.length === 0    // without any numbers,
    ? undefined     // there can be no reduction.
: i + 1 >= a.length // if the next i is not in bounds,
    ? a[i]          // this is the last element
    : f(a[i], reduce(f, a, i + 1)) // else

const getMax = (numbers = []) =>
  reduce(max, numbers) // <-- our reduce!

console.log(getMax([1, 2, 3, 4, 4, 5, 1, 3, 4]))
// 5

console.log(getMax([]))
// undefined

console.log(getMax())
// undefined
0 голосов
/ 30 апреля 2020

Попробуйте использовать метод Math.max:

const numbers = [1, 2, 3, 4, 4, 5, 1, 3, 4]
numbers.reduce((acc, rec) => Math.max(acc, rec))

//5

или

function max(numbers) {
  return list.reduce((acc, rec) => acc > rec ? acc : rec)
}

, если вам нужно найти максимальное значение без Math.max.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...