#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(), но я вижу, что я сделал это сложнее, чем вы.