Уменьшить массив объектов по user_id и суммировать определенные значения - PullRequest
0 голосов
/ 18 декабря 2018

У меня есть массив объектов, который выглядит следующим образом:

"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 до каждого уникальногоuser
  • , затем вычислите общее количество shotAttempts и shotsMade для каждого пользователяФункция .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 голосов
/ 18 декабря 2018

Вы можете использовать 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);
0 голосов
/ 18 декабря 2018

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);
0 голосов
/ 18 декабря 2018

Вы можете использовать Array.reduce, Object.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))
...