通过user_id减少对象数组并求和某些值

时间:2018-12-18 04:51:56

标签: javascript arrays object reduce

我有一个看起来像这样的对象数组:

"data": [
{ "workout_id": 1, "user_id": 1, "shotLocation": 27, "shotAttempts": 20,"shotsMade": 19, "id": 1 },
{ "workout_id": 2, "user_id": 1, "shotLocation": 1, "shotAttempts": 10, "shotsMade": 9, "id": 2 },
{ "workout_id": 2, "user_id": 1, "shotLocation": 10, "shotAttempts": 10, "shotsMade": 7, "id": 3 },
{ "workout_id": 2, "user_id": 1, "shotLocation": 1, "shotAttempts": 30, "shotsMade": 29, "id": 4 },
{ "workout_id": 3, "user_id": 5, "shotLocation": 1, "shotAttempts": 10, "shotsMade": 9, "id": 5 },
{ "workout_id": 4, "user_id": 6, "shotLocation": 1, "shotAttempts": 30, "shotsMade": 15, "id": 6 },
{ "workout_id": 4, "user_id": 6, "shotLocation": 2, "shotAttempts": 20, "shotsMade": 14, "id": 7 }
]

我想在其中创建一个新的对象数组

  • 减少每个唯一用户的user_ids
  • 然后计算每个用户的总出手次数和出手次数

像这样:

"dataTotals" : [
{"id": 1, "user_id": 1, "shotAttempts": 90, "shotsMade": 64}
{"id": 2, "user_id": 5, "shotAttempts": 10, "shotsMade": 9}
{"id": 3, "user_id": 6, "shotAttempts": 50, "shotsMade": 29}

我计划使用.map函数在这个新的对象数组上进行迭代,以在更多用户记录其数据时填充页首横幅。

根据我对.map和.reduce方法的了解,我尝试了几种不同的方法来实现此目的,并在此处进行搜索并找到了接近的内容,但它返回一个对象,如下所示。

像这样:

// create new object to store results in
let newObj = {};
// loop through user objects
this.state.shotlogs.forEach(function(shotlog){
// check if user_id  has already been added to newObj
if(!newObj[shotlog.user_id]){
// If it is the first time seeing this user_id
// we need to add shots attempted and shots made to prevent errors
newObj[shotlog.user_id] = {};
newObj[shotlog.user_id]['user_id'] = shotlog.user_id;
newObj[shotlog.user_id]['shotAttempts'] = 0;
newObj[shotlog.user_id]['shotsMade'] = 0;
}
// add shots attempted and made to newObj for this user
newObj[shotlog.user_id]['shotAttempts'] += shotlog.shotAttempts
newObj[shotlog.user_id]['shotsMade'] += shotlog.shotsMade
})

但这会返回一个看起来像这样的对象,而不是上面的对象数组:

{
1: {user_id: 1, shotAttempts: 70, shotsMade: 64}
5: {user_id: 5, shotAttempts: 10, shotsMade: 9}
6: {user_id: 6, shotAttempts: 50, shotsMade: 29}
}

对于这种新编码器的任何帮助,我们将不胜感激!

3 个答案:

答案 0 :(得分:0)

您可以将Array.reduceObject.values ES6 一起使用,并以简洁的方式解决此问题:

const data = [{ "workout_id": 1, "user_id": 1, "shotLocation": 27, "shotAttempts": 20, "shotsMade": 19, "id": 1 }, { "workout_id": 2, "user_id": 1, "shotLocation": 1, "shotAttempts": 10, "shotsMade": 9, "id": 2 }, { "workout_id": 2, "user_id": 1, "shotLocation": 10, "shotAttempts": 10, "shotsMade": 7, "id": 3 }, { "workout_id": 2, "user_id": 1, "shotLocation": 1, "shotAttempts": 30, "shotsMade": 29, "id": 4 }, { "workout_id": 3, "user_id": 5, "shotLocation": 1, "shotAttempts": 10, "shotsMade": 9, "id": 5 }, { "workout_id": 4, "user_id": 6, "shotLocation": 1, "shotAttempts": 30, "shotsMade": 15, "id": 6 }, { "workout_id": 4, "user_id": 6, "shotLocation": 2, "shotAttempts": 20, "shotsMade": 14, "id": 7 } ]

const result = data.reduce((r,{workout_id, user_id, shotAttempts, shotsMade}) => {
 r[user_id] = r[user_id] || {id: workout_id, user_id, shotAttempts: 0, shotsMade: 0}
 r[user_id].shotAttempts += shotAttempts
 r[user_id].shotsMade += shotsMade
 return r
}, {})

console.log(Object.values(result))

答案 1 :(得分:0)

您可以使用Array.prototype.reduce()

代码:

const data = [{ "workout_id": 1, "user_id": 1, "shotLocation": 27, "shotAttempts": 20,"shotsMade": 19, "id": 1 },{ "workout_id": 2, "user_id": 1, "shotLocation": 1, "shotAttempts": 10, "shotsMade": 9, "id": 2 },{ "workout_id": 2, "user_id": 1, "shotLocation": 10, "shotAttempts": 10, "shotsMade": 7, "id": 3 },{ "workout_id": 2, "user_id": 1, "shotLocation": 1, "shotAttempts": 30, "shotsMade": 29, "id": 4 },{ "workout_id": 3, "user_id": 5, "shotLocation": 1, "shotAttempts": 10, "shotsMade": 9, "id": 5 },{ "workout_id": 4, "user_id": 6, "shotLocation": 1, "shotAttempts": 30, "shotsMade": 15, "id": 6 },{ "workout_id": 4, "user_id": 6, "shotLocation": 2, "shotAttempts": 20, "shotsMade": 14, "id": 7 }];
const dataTotals = Object.values(data.reduce((a, c) => {
  if (!a[c.user_id]) {
    a[c.user_id] = {
      id: c.workout_id,
      user_id: c.user_id,
      shotAttempts: c.shotAttempts,
      shotsMade: c.shotsMade
    };
  } else {  
    a[c.user_id].shotAttempts += c.shotAttempts;
    a[c.user_id].shotsMade += c.shotsMade;
  }
  return a;
}, {}));

console.log(dataTotals);

答案 2 :(得分:0)

const data = [
  { workout_id: 1, user_id: 1, shotLocation: 27, shotAttempts: 20, shotsMade: 19, id: 1 },
  { workout_id: 2, user_id: 1, shotLocation: 1, shotAttempts: 10, shotsMade: 9, id: 2 },
  { workout_id: 2, user_id: 1, shotLocation: 10, shotAttempts: 10, shotsMade: 7, id: 3 },
  { workout_id: 2, user_id: 1, shotLocation: 1, shotAttempts: 30, shotsMade: 29, id: 4 },
  { workout_id: 3, user_id: 5, shotLocation: 1, shotAttempts: 10, shotsMade: 9, id: 5 },
  { workout_id: 4, user_id: 6, shotLocation: 1, shotAttempts: 30, shotsMade: 15, id: 6 },
  { workout_id: 4, user_id: 6, shotLocation: 2, shotAttempts: 20, shotsMade: 14, id: 7 }
];

const shooters = data.reduce(
  (results, current) => ({
    ...results,
    [current.user_id]: {
      user_id: current.user_id,
      shotAttempts: current.shotAttempts + (results[current.user_id] ? results[current.user_id].shotAttempts : 0),
      shotsMade: current.shotsMade + (results[current.user_id] ? results[current.user_id].shotsMade : 0)
    }
  }),
  {}
);

console.log(shooters);