#javascript #arrays
#javascript #массивы
Вопрос:
У меня есть такой массив:
[
{
group: "perf",
subgroups: [
{
date: "2020-08-20",
number: 2
},
{
date: "2020-08-21",
number: 3
}
],
number: 5
},
{
group: "mobile",
subgroups: [
{
date: "2020-08-20",
number: 4
},
{
date: "2020-08-21",
number: 6
}
],
number: 10
},
{
group: "games",
subgroups: [
{
date: "2020-08-20",
number: 7
},
{
date: "2020-08-21",
number: 8
},
{
date: "2020-08-22",
number: 1
}
],
number: 16
},
{
group: "levels",
subgroups: [
{
date: "2020-08-09",
number: 4
},
{
date: "2020-08-20",
number: 9
},
{
date: "2020-08-21",
number: 11
}
],
number: 24
}
]
Цель состоит в том, чтобы преобразовать этот массив в такой формат.
[
{
date: "2020-08-09",
total: 4,
issues: [
{ name: levels, count: 4 }
]
},
{
date: "2020-08-20",
total: 22,
issues: [
{ name: perf, count: 2 },
{ name: mobile, count: 4 },
{ name: games, count: 7 },
{ name: levels, count: 9 },
]
},
{
date: "2020-08-21",
total: 28,
issues: [
{ name: perf, count: 3 },
{ name: mobile, count: 6 },
{ name: games, count: 8 },
{ name: levels, count: 11 },
]
},
{
date: "2020-08-22",
total: 1,
issues: [
{ name: games, count: 1 },
]
}
]
итого — общая сумма чисел за конкретную дату.
Вот что я пробовал до сих пор. Мой единственный вопрос заключается в том, как сгруппировать поля во вложенный массив? https://jsfiddle.net/7g3tLo0q /
const arr = [
{
"group": "perf",
"subgroups": [
{
"date": "2020-08-20",
"number": 2
},
{
"date": "2020-08-21",
"number": 3
}
],
"number": 5
},
{
"group": "mobile",
"subgroups": [
{
"date": "2020-08-20",
"number": 4
},
{
"date": "2020-08-21",
"number": 6
}
],
"number": 10
},
{
"group": "games",
"subgroups": [
{
"date": "2020-08-20",
"number": 7
},
{
"date": "2020-08-21",
"number": 8
},
{
"date": "2020-08-22",
"number": 1
}
],
"number": 16
},
{
"group": "levels",
"subgroups": [
{
"date": "2020-08-09",
"number": 4
},
{
"date": "2020-08-20",
"number": 9
},
{
"date": "2020-08-21",
"number": 11
}
],
"number": 24
}
]
/* expected
[
{
date: "2020-08-09",
total: 4,
issues: [
{ name: levels, count: 4 }
]
},
{
date: "2020-08-20",
total: 22,
issues: [
{ name: perf, count: 2 },
{ name: mobile, count: 4 },
{ name: games, count: 7 },
{ name: levels, count: 9 },
]
},
{
date: "2020-08-21",
total: 28,
issues: [
{ name: perf, count: 3 },
{ name: mobile, count: 6 },
{ name: games, count: 8 },
{ name: levels, count: 11 },
]
},
{
date: "2020-08-22",
total: 1,
issues: [
{ name: games, count: 1 },
]
}
]
*/
const dateValueLookup = arr.reduce((acc, el) => {
el.subgroups.forEach((subgroup) => {
if (!acc[subgroup.date]) {
acc[subgroup.date] = {}
}
if (!acc[subgroup.date][el.group]) {
acc[subgroup.date][el.group] = 0
}
acc[subgroup.date][el.group] = subgroup.number
})
return acc
}, {})
const res = Object.entries(dateValueLookup)
.sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
.map(([date, values]) => ({
date,
total: Object.values(values).reduce((sum, value) => sum value, 0),
...values,
}))
console.log(res, 'res');
Спасибо!
Комментарии:
1. пожалуйста, добавьте свой код к вопросу.
2. Добавлено @NinaScholz
Ответ №1:
Вы могли бы использовать вложенные циклы и сокращать группы и подгруппы и применять сортировку по date
.
const
data = [{ group: "perf", subgroups: [{ date: "2020-08-20", number: 2 }, { date: "2020-08-21", number: 3 }], number: 5 }, { group: "mobile", subgroups: [{ date: "2020-08-20", number: 4 }, { date: "2020-08-21", number: 6 }], number: 10 }, { group: "games", subgroups: [{ date: "2020-08-20", number: 7 }, { date: "2020-08-21", number: 8 }, { date: "2020-08-22", number: 1 }], number: 16 }, { group: "levels", subgroups: [{ date: "2020-08-09", number: 4 }, { date: "2020-08-20", number: 9 }, { date: "2020-08-21", number: 11 }], number: 24 }],
result = data
.reduce((r, { group: name, subgroups }) => subgroups.reduce((days, { date, number: count }) => {
let day = days.find(q => q.date === date);
if (!day) days.push(day = { date, total: 0, issues: [] });
day.issues.push({ name, count });
day.total = count;
return days;
}, r), [])
.sort((a, b) => a.date.localeCompare(b.date));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Ответ №2:
const dateValueLookup = arr.reduce((acc, el) => {
el.subgroups.forEach((subgroup) => {
if (!acc[subgroup.date]) {
acc[subgroup.date] = {}
}
if (!acc[subgroup.date][el.group]) {
acc[subgroup.date][el.group] = 0
}
acc[subgroup.date][el.group] = subgroup.number
})
return acc
}, {})
const res = Object.entries(dateValueLookup)
.sort(([keyA], [keyB]) => keyA.localeCompare(keyB))
.map(([date, values]) => ({
date,
total: Object.values(values).reduce((sum, value) => sum value, 0),
...values,
}))
const fres = res.map((value, key)=>{
value.issues = [];
for (const key in value) {
if(key=='total' || key=='issues' || key=='date'){
continue;
}
value.issues.push({name:key, count:value.total})
}
return value;
}
);
console.log(fres);
Демонстрация:https://jsfiddle.net/yj9b12z3/34 /