#javascript #lodash #uniq
#javascript #lodash #uniq
Вопрос:
Как я могу сделать свои данные:
[
{
"a": {
"b": 1,
"c": "M"
},
"color": "white"
},
{
"a": {
"b": 10,
"c": "M"
},
"color": "white"
}
]
в это:
[
{
"a": {
"b": 11,
"c": "M"
},
"color": "white"
}
]
Я бы хотел a.c
color
, чтобы поля and были уникальными и a.b
объединялись.
Я пробовал использовать _.uniq
, но это не работает. Я использую lodash 3.10.1.
Ответ №1:
Не тривиально, но вот оно:
// assuming the data is in `data`:
_.map(_.groupBy(data, x => [x.a.c, x.color]),
x => _.tap(_.cloneDeep(x[0]), y => y.a.b = _.sum(x, z => z.a.b)))
Сначала я группирую объекты по составному значению .a.c
и .color
; в каждой группе я клонирую первый объект, который будет результатом, затем перезаписываю его .a.b
значение суммой всех .a.b
значений в группе.
РЕДАКТИРОВАТЬ: в обернутом синтаксисе:
_(data).groupBy(x => [x.a.c, x.color]).map(x =>
_.tap(_.cloneDeep(x[0]), y => y.a.b = _.sum(x, z => z.a.b))
).value()
Комментарии:
1. Хорошее решение! Может быть, мы могли бы использовать цепочку, чтобы сделать ее более читаемой, например
_(data).groupBy(x => ...).map(x => ...).value()
🙂2. вау! решение, которое вы дали, довольно сложно понять, но я постараюсь. спасибо вам. 🙂
3. @GuilhermeSehn: Я согласен, у меня не такой опыт работы с Lodash, и я действительно не знал об упаковке. Но я бы завернул только переднюю часть, потому что в противном случае вы окажетесь в оберточном аду.
4. @Amadan согласен!
Ответ №2:
Другой подход:
var f = [{
"a": {
"b": 1,
"c": "M"
},
"color": "white"
}, {
"a": {
"b": 10,
"c": "M"
},
"color": "white"
}];
var res = _.reduce(f, (memo, o) => {
var already = _.find(memo, o1 => o.a.c === o1.a.c || o.color === o1.color);
return already ? (already.a.b = o.a.b, memo) : memo.concat(o);
}, []);
console.log(res);
<script src="https://cdn.jsdelivr.net/lodash/3.10.0/lodash.min.js"></script>
Идея здесь состоит в том, чтобы иметь массив (результирующий массив), в котором у нас есть уникальные объекты. Затем мы выполняем итерацию по исходному массиву: если текущий объект итерации находится в результирующем массиве, мы обновляем значение и ничего не добавляем. Если это не так, мы просто добавляем его.
Надеюсь, это поможет.