Как отобразить объект с помощью метода reduce?

#javascript #class #object

#javascript #класс #объект

Вопрос:

Я попытался создать класс Person с собственным методом map, который я назвал mapper. Требуется использовать метод reduce и отправить обратный вызов mapper.

 class Person {
  constructor(name, age, job) {
    this.name = name
    this.age = age
    this.job = job
  }
  mapper(cb) {
    return Object.entries(this).reduce((acc, item) => {
      acc = cb(item)
      return acc
    }, {})
  }
}
  

Я создаю экземпляр этого класса.

 const kate = new Person('Kate', 34, 'dev')
const result = kate.mapper(([key, val]) => (val === 34 ? { [key]: val } : {}))
console.log(result)
// {}
  

Я должен получить свой результат в виде

 // {age: 34}
  

Проблема в том, что значение acc равно последнему условию (при сравнении с заданием).
Похоже, что acc постоянно перезаписывается во время итерации.
Я пытался решить эту проблему, используя метод forEach look в mapper, но я получил некоторые ошибки. Обратный вызов должен выглядеть так же, как сейчас. Я знаю, что я должен изменить sth в mapper, но я понятия не имею, что. Я тоже пытался использовать Object.assing().

Комментарии:

1. «Требование заключается в использовании метода reduce …» Чье это требование? reduce редко является подходящим инструментом для поиска (вне функционального программирования с предопределенными, проверенными функциями редуктора). В противном случае reduce является чрезмерно сложным и трудным для чтения.

2. Что не так с map ? Почему вы просто заново изобретаете колесо чрезмерно тупым способом?

3. Ваш .reduce() обратный вызов всегда возвращает возвращаемое значение cb(item) . Таким образом, конечным результатом .mapper() является возвращаемое значение последнего cb(item) вызова, которое будет пустым массивом — если age свойство каким-либо образом не станет последним элементом в массиве и не будет иметь значение 34

4. @T.J.Crowder Я только что получил упражнение от своего учителя. Вероятно, причина в том, чтобы изучить более сложный способ решения этой проблемы. Если я смогу использовать только map, я не буду писать этот пост…

5. Я подумал, что это было что-то вроде этого. 🙂 Похоже, ваш учитель был заражен ошибкой «это массив, я думаю, я должен использовать reduce «. FWIW: twitter.com/bterlson/status/1099010861065068544 , twitter.com/jaffathecake/status/1213077702300852224 Счастливого кодирования!

Ответ №1:

Похоже, что acc постоянно перезаписывается во время итерации.

Это правильно, потому что вы получаете новый объект из cb , а затем возвращаете этот объект.

Если вы хотите объединить объекты, возвращаемые cb , вы можете изменить его на использование Object.assign для копирования свойств объекта, возвращаемого cb на acc :

 mapper(cb) {
  return Object.entries(this).reduce((acc, item) => {
    Object.assign(acc, cb(item)); // ***
    return acc;
  }, {});
}
  

…но на самом деле, reduce это просто не тот инструмент, который нужно использовать здесь; накопитель никогда не меняется (мы просто модифицируем его). Тем не менее, вы сказали, что это требование…

Вы также можете комбинировать

     Object.assign(acc, cb(item)); // ***
    return acc;
  

в

     return Object.assign(acc, cb(item)); // ***
  

поскольку Object.assign возвращает его первый аргумент ( acc , в приведенном выше).

Комментарии:

1. Большое спасибо! Это работает. Как я уже упоминал, я пытался сделать это с помощью Object.assign(), но я вижу, что я сделал это сложнее, чем вы.