Свойство Sum на основе различных значений с помощью lodash

#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> 

Идея здесь состоит в том, чтобы иметь массив (результирующий массив), в котором у нас есть уникальные объекты. Затем мы выполняем итерацию по исходному массиву: если текущий объект итерации находится в результирующем массиве, мы обновляем значение и ничего не добавляем. Если это не так, мы просто добавляем его.

Надеюсь, это поможет.