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