Использование JavaScript Reduce для генерации объекта - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть массив чисел [22, 44, 12, 9, 4, 23, 1, 11, 10, 5, 2, 123], мне нужно использовать Reduce для создания объекта, который выглядит следующим образом:

{  
   numbersLessThanTen: [...],  
   numbersGreaterThanTen: [...]
}

У меня есть решение, которое приведено ниже:

const listOfNumbers = [22, 44, 12, 9, 4, 23, 1, 11, 10, 5, 2, 123];


const groupedBySize = listOfNumbers.reduce((total, next) => {
  const less = total.numbersLessThanTen || [];
  const more = total.numbersGreaterThanTen || [];
  
  next > 10 ? total.numbersGreaterThanTen = [].concat(more, next) : total.numbersLessThanTen = [].concat(less, next);
  return total;
  
}, {});

Мой вопрос: почему не работает следующее?Он просто возвращает начальное значение.Это работает, когда я использую .push () вместо .concat (), но я действительно хочу понять, почему этот способ не работает.Спасибо!

const groupedBySize = listOfNumbers.reduce((total, next) => {
  // const less = total.numbersLessThanTen || [];
  // const more = total.numbersGreaterThanTen || [];
  
  next > 10 ? total.numbersGreaterThanTen.concat(next) : total.numbersLessThanTen.concat(next);
  return total;

}, {numbersGreaterThanTen: [], numbersLessThanTen:[]});

Ответы [ 4 ]

0 голосов
/ 03 декабря 2018

Вы можете решить, какой массив с троичным, а затем push() вместо concat():

let n = [22, 44, 12, 9, 4, 23, 1, 11, 10, 5, 2, 123]

let obj = n.reduce((obj, n) => {
    (n < 10 
     ? obj.numbersLessThanTen
     : obj.numbersGreaterThanTen
    ).push(n)
    return obj
}, {numbersLessThanTen: [],  numbersGreaterThanTen:[]})

console.log(obj)
0 голосов
/ 03 декабря 2018

Array.concat не не изменяет массив, в котором он вызывается.Вы предполагаете это и не назначаете результат чему-либо ... согласно документам:

Этот метод не изменяет существующие массивы, а вместо этого возвращает новый массив

Таким образом, чтобы получить то, что вы хотите с вашим кодом, вы можете сделать что-то вроде этого:

const listOfNumbers = [22, 44, 12, 9, 4, 23, 1, 11, 10, 5, 2, 123];

const groupedBySize = listOfNumbers.reduce((total, next) => {  
  let key = next > 10 ? 'numbersGreaterThanTen' : 'numbersLessThanTen'
  total[key] = total[key].concat([next]); // <-- assign the result
  return total;
}, {numbersGreaterThanTen: [], numbersLessThanTen: []});

console.log(groupedBySize)

В качестве альтернативы вы можете просто сделать это:

const listOfNumbers = [22, 44, 12, 9, 4, 23, 1, 11, 10, 5, 2, 123];

const groupedBySize = listOfNumbers.reduce((ttl, nxt) => 
 (ttl[nxt > 10 ? 'numbersGreaterThanTen' : 'numbersLessThanTen'].push(nxt), ttl), 
 {numbersGreaterThanTen: [], numbersLessThanTen:[]});

console.log(groupedBySize)

Который делает то же самое, но использует Array.push, который mutates массив, к которому он вызывается при вставке элемента.

0 голосов
/ 03 декабря 2018

Другие объяснили, почему этот подход не работал, и дали разумные ответы, продолжая мутацию.

Вот подход, который не изменяет никакие данные:

const listOfNumbers = [22, 44, 12, 9, 4, 23, 1, 11, 10, 5, 2, 123];

const groupedBySize = nbr => nbr.reduce 
  ( ({ gt10, lte10 }, next) => next > 10 
     ? { gt10: gt10 .concat(next), lte10 } 
     : { gt10, lte10: lte10 .concat(next) }
  , { gt10: [], lte10: [] }
  )

console.log(groupedBySize(listOfNumbers))

Я также сократил имена свойств.Очевидно, вы могли бы удлинить их.Но учтите, что "numbersLessThanTen" немного вводит в заблуждение, поскольку включает 10.

0 голосов
/ 03 декабря 2018

Причина, по которой ваш код не работает, заключается в том, что concat() возвращает результат объединения в виде нового массива.Когда ваша функция выполнения выполняется, работа по конкатенации завершается, но результат этой конкатенации никому не назначается (т. Е. Поле в total).По этой причине выводимый результат совпадает с входным: массивы в total фактически никогда не обновляются. следует из MDN

Метод concat создает новый массив, состоящий из элементов объекта, для которого он вызывается.

push() метод, с другой стороны, фактически изменяет / обновляет массив, к которому он вызывается, добавляя все данные, которые вы передаете, непосредственно в этот экземпляр массива.Это означает, что когда push() вызывается на итерацию, массивы в total обновляются напрямую, поэтому этот подход работает:

Метод push добавляет значения в массив.

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