Nodejs - 通过添加具有相同键的值来返回键值对的数组

时间:2017-11-15 16:07:28

标签: node.js ramda.js

我有以下对象数组:

const list = [
  {points: 3, name:'bob'},
  {points: 1, name:'john'},
  {points: 5, name:'john'},
  {points: 2, name:'john'},
  {points: 8, name:'john'},
  {points: 0, name:'bob'},
  {points: 2, name:'bob'},
  {points: 1, name:'bob'},
]

我希望最终得到一个对象,它返回一个数据集列表,其中包含每个名称的总和,如:

const list2 = [
  {name: 'bob', points: 6}, // sum of all of bob's points
  {name: 'john', points: 16}
]

我需要这个,以便我可以使用结果数据集生成折线图。

有没有办法做到这一点,最好使用ramda.js

2 个答案:

答案 0 :(得分:3)

你可以这样做:

var combine = pipe(
  groupBy(prop('name')), //=> {bob: [bob_obj_1, bob_obj_2, ...], john: [ ... ]}
  map(pluck('points')),  //=> {bob: [3, 0, 2, 1], john: [1, 5, 2, 8]}
  map(sum)               //=> {bob: 6, john: 16}
)

或者您可以使用reduce,但我认为这更简单。

更新:我误读了输出格式。这解决了它:

var combine = pipe(
  groupBy(prop('name')), //=> {bob: [bob_obj_1, bob_obj_2, ...], john: [ ... ]}
  map(pluck('points')),  //=> {bob: [3, 0, 2, 1], john: [1, 5, 2, 8]}
  map(sum),              //=> {bob: 6, john: 16}
  toPairs,               //=> [["bob", 6], ["john", 16]]
  map(zipObj(['name', 'points'])) //=> [{name: "bob", points: 6}, 
                         //             {name: "john", points: 16}]
)

答案 1 :(得分:0)

这是Array.prototype.reduce()Object.keys()

的一个相当简单的用法
const list = [
  {points: 3, name:'bob'},
  {points: 1, name:'john'},
  {points: 5, name:'john'},
  {points: 2, name:'john'},
  {points: 8, name:'john'},
  {points: 0, name:'bob'},
  {points: 2, name:'bob'},
  {points: 1, name:'bob'},
]

const map = list.reduce((prev, next) => {
  // if the name has not already been observed, create a new entry with 0 points
  if (prev[next.name] == null) {
    prev[next.name] = 0;
  }

  // add the new points
  prev[next.name] += next.points;

  return prev;
}, {});

// map is now an object containing { [name]: [points] }
// convert this back into an array of entries
const list2 = Object.keys(map)
  .map(name => ({ name, points: map[name] }));

console.log(list2)
// [ { name: 'bob', points: 6 }, { name: 'john', points: 16 } ]