React / ES6 уменьшает объект

#javascript #ecmascript-6

#javascript #ecmascript-6

Вопрос:

У меня есть следующий объект, который содержит тренировки в течение определенных дней:

 {
  "2019-03-02": [
    {
        "id": 1,
        "workout_day": "2019-03-02",
        "title": "Swimming",
        "description": "",
        "completed": true,
        "points": 5
    },
    {
        "id": 2,
        "workout_day": "2019-03-02",
        "title": "Running",
        "description": "",
        "completed": false,
        "points": 0
    },
    {
        "id": 3,
        "workout_day": "2019-03-02",
        "title": "Rowing",
        "description": "",
        "completed": true,
        "points": 3
    },
  ],
 "2019-03-05": [...]
}
  

Я хочу получить новый объект, который показывает за каждый день, сколько существует тренировок, сколько из них было завершено, и сумму баллов, вот так:

 {
  "2019-03-02": {
    "workouts": 3,
    "workouts_completed": 2,
    "total_points": 8
  },
  "2019-03-05: {...}
}
  

Однако на данный момент я полностью застрял. Спасибо за помощь!

Комментарии:

1. Пожалуйста, поделитесь своими попытками.

Ответ №1:

Для достижения этой цели у вас есть несколько решений. Вот тот, который объединил Object.entries Array.reduce .

 Object.entries(input).reduce((acc, [date, workouts]) => {
  const completed = workouts.filter(workout => workout.completed);

  return {
    ...acc,
    [date]: {
      workouts: workouts.length,
      workouts_completed: completed.length,
      total_points: completed.reduce((acc, workout) => acc   workout.points, 0),
    }
  };
}, {});
  

Обратите внимание, что Object.entries это доступно не во всех основных браузерах.

Ответ №2:

Это уменьшит ваши данные до тех, в которые вы хотите преобразовать

 const data = {
  '2019-03-02': [{
      id: 1,
      workout_day: '2019-03-02',
      title: 'Swimming',
      description: '',
      completed: true,
      points: 5
    },
    {
      id: 2,
      workout_day: '2019-03-02',
      title: 'Running',
      description: '',
      completed: false,
      points: 0
    },
    {
      id: 3,
      workout_day: '2019-03-02',
      title: 'Rowing',
      description: '',
      completed: true,
      points: 3
    }
  ],
  '2019-03-03': [{
      id: 1,
      workout_day: '2019-03-02',
      title: 'Swimming',
      description: '',
      completed: true,
      points: 7
    },
    {
      id: 2,
      workout_day: '2019-03-02',
      title: 'Running',
      description: '',
      completed: false,
      points: 0
    },
    {
      id: 3,
      workout_day: '2019-03-02',
      title: 'Rowing',
      description: '',
      completed: false,
      points: 3
    }
  ]
}

const reducedData = Object.keys(data).reduce((acc, key) => {
  acc[key] = {
    workouts: data[key].length,
    workouts_completed: data[key].reduce((acc, item) => {
      if (item.completed) return acc   1
      return acc
    }, 0),
    total_points: data[key].reduce((acc, item) => {
      return acc   item.points
    }, 0)
  }
  return acc
}, {})

console.log(reducedData)  

Ответ №3:

Предполагая, что у вас есть объект, который хранит тренировки в течение определенных дней в вызываемом объекте json , вы можете использовать Object.keys() для перебора всех ключей. Затем вы можете map изменить это и получать тренировки на один конкретный день за раз. Затем вы можете использовать это для создания объекта на каждый день. Для вычисления таких вещей, totalPoints которые вы будете использовать reduce для суммирования общего количества баллов.

 Object.keys(json).map(key => {
    return {
        [key]: {
            workoutsCompleted: json[key].length,
            totalPoints: json[key].reduce((accum, workout) => accum   workout.points, 0)
        }
    };
});
  

Ответ №4:

Это делает свое дело.

Я использовал Array.prototype.reduce и деструктурирование со значениями по умолчанию.

 var data = {
  "2019-03-02": [{
      "id": 1,
      "workout_day": "2019-03-02",
      "title": "Swimming",
      "description": "",
      "completed": true,
      "points": 5
    }, {
      "id": 2,
      "workout_day": "2019-03-02",
      "title": "Running",
      "description": "",
      "completed": false,
      "points": 0
    }, {
      "id": 3,
      "workout_day": "2019-03-02",
      "title": "Rowing",
      "description": "",
      "completed": true,
      "points": 3
    },
  ],
  "2019-03-05": [{
      "id": 1,
      "workout_day": "2019-03-02",
      "title": "Swimming",
      "description": "",
      "completed": false,
      "points": 0
    }, {
      "id": 2,
      "workout_day": "2019-03-02",
      "title": "Running",
      "description": "",
      "completed": false,
      "points": 0
    }, {
      "id": 3,
      "workout_day": "2019-03-02",
      "title": "Rowing",
      "description": "",
      "completed": true,
      "points": 8
    },
  ]
};

var result = {};

for (let key in data) {
  result[key] = data[key].reduce(({
        workouts = 0,
        workouts_completed = 0,
        total_points = 0
      }, currentValue) => {
      return {
        workouts: workouts   1,
        workouts_completed: currentValue.completed ? workouts_completed   1 : workouts_completed,
        total_points: total_points   currentValue.points
      };
    }, {});
}

console.log(result);  

Ответ №5:

  const result = {};

 for(const [workout_day, entries] of Object.entries(input)) {
   result[workout_day] = { 
     workouts: entries.length,
     workouts_completed: entries.reduce((acc, e) => acc   e.completed, 0),
     total_points: entries.reduce((acc, e) => acc   e.points, 0),
  };
}
  

Object.entries довольно полезен для отображения объектов.

Ответ №6:

 const data = {
  "2019-03-02": [
    {
        "id": 1,
        "workout_day": "2019-03-02",
        "title": "Swimming",
        "description": "",
        "completed": true,
        "points": 5
    },
    {
        "id": 2,
        "workout_day": "2019-03-02",
        "title": "Running",
        "description": "",
        "completed": false,
        "points": 0
    },
    {
        "id": 3,
        "workout_day": "2019-03-02",
        "title": "Rowing",
        "description": "",
        "completed": true,
        "points": 3
    },
  ],
 "2019-03-05": []
};

function makeReport (report, workout) {
  return {
    workouts: report.workouts   1,
    workouts_completed: workout.completed ? report.workouts_completed   1 : report.workouts_completed,
    total_points: report.total_points   workout.points
  };
}

const out = Object.entries(data).reduce(function (report, [date, workouts]) {
  return {
    ...report,
    [date]: workouts.reduce(makeReport, { workouts: 0, workouts_completed: 0, total_points: 0 })
  };
}, {});

console.log(out);
  

какие журналы:

 { '2019-03-02': { workouts: 3, workouts_completed: 2, total_points: 8 },
  '2019-03-05': { workouts: 0, workouts_completed: 0, total_points: 0 } }