#javascript #node.js #lodash
Вопрос:
Это исходный массив:
[
{
id: robin,
savings: 5500,
cost: 1200
},
{
id: robin_1,
savings: 50,
cost: 100
},
{
id: robin_2,
savings: 50,
cost: 150
},
{
id: steve,
savings: 100,
cost: 1000
},
{
id: steve_1,
savings: 50,
cost: 550
},
{
id: steve_2,
savings: 50,
cost: 150
},
]
Я пытаюсь получить результат ниже ожидаемого .
{
robin :{
allTime:{
savings: 5500,
cost: 1200,
},
today:{
savings: 100,
cost: 250
}
},
steve:{
allTime: {
savings:100,
cost: 1000
},
today: {
savings: 100,
cost: 700
}
}
}
В основном, когда идентификатор-это только робин, установите вывод в ключе allTime, и когда после робина есть некоторые суффиксы, такие как 1,2,3, затем суммируйте их и установите в «сегодня».
Пробовали, обычно зацикливая их и группируя с помощью _.sumBy (), как показано ниже, но потерпели неудачу.
var output = _.groupBy(resultSet, value => value.id)
.map((objs, key) => (
{ 'id': key,
'savings': _.sumBy(objs,'savings'),
'cost': _.sumBy(objs, 'cost'))
}
.value();
Комментарии:
1. «Пробовали, обычно зацикливая их» не могли бы вы, пожалуйста, включить свои попытки? Таким образом, мы можем помочь вам понять их и дать ответ на ваш вопрос.
2. @Reyno Добавил мою попытку . Было бы очень полезно, если бы вы могли мне помочь.
Ответ №1:
Мне удалось сделать это так, используя array#reduce
:
let data = [
{ id: 'robin', savings: 5500, cost: 1200 },
{ id: 'robin_1', savings: 50, cost: 100 },
{ id: 'robin_2', savings: 50, cost: 150 },
{ id: 'steve', savings: 100, cost: 1000 },
{ id: 'steve_1', savings: 50, cost: 550 },
{ id: 'steve_2', savings: 50, cost: 150 },
];
let newData = data.reduce((acc, { id, savings, cost }) => {
let [pre, suff] = id.split('_');
if (!acc[pre]) acc[pre] = { allTime: {}, today: { savings: 0, cost: 0 } };
if (!suff) acc[pre].allTime = { savings, cost };
else (acc[pre].today.savings = savings), (acc[pre].today.cost = cost);
return acc;
}, {});
console.log(newData);
И вот так, используя for...of
петлю:
let data = [
{ id: 'robin', savings: 5500, cost: 1200 },
{ id: 'robin_1', savings: 50, cost: 100 },
{ id: 'robin_2', savings: 50, cost: 150 },
{ id: 'steve', savings: 100, cost: 1000 },
{ id: 'steve_1', savings: 50, cost: 550 },
{ id: 'steve_2', savings: 50, cost: 150 },
];
let newData = {};
for ({ id, savings, cost } of data) {
let [pre, suff] = id.split('_');
if (!newData[pre]) newData[pre] = { allTime: {}, today: { savings: 0, cost: 0 } };
if (!suff) newData[pre].allTime = { savings, cost };
else (newData[pre].today.savings = savings), (newData[pre].today.cost = cost);
}
console.log(newData)
Ответ №2:
Попробуйте сделать это циклически, уменьшив
const data = [
{
id: "robin",
savings: 5500,
cost: 1200
},
{
id: "robin_1",
savings: 50,
cost: 100
},
{
id: "robin_2",
savings: 50,
cost: 150
},
{
id: "steve",
savings: 100,
cost: 1000
},
{
id: "steve_1",
savings: 50,
cost: 550
},
{
id: "steve_2",
savings: 50,
cost: 150
},
];
const res = data.reduce((acc, val) => {
const splitVal = val.id.split("_")[0];
if(acc[val.id] || acc[splitVal]){
acc[splitVal].today.savings =val.savings;
acc[splitVal].today.cost =val.cost;
}else{
acc[val.id] = {
allTime:{
savings: val.savings,
cost: val.cost,
},
today:{
savings: 0,
cost: 0
}
}
}
return acc;
}, {});
console.log(res);
Ответ №3:
Я думаю, что я бы пошел Array.prototype.reduce()
вот так:
const input = [
{ id: 'robin', savings: 5500, cost: 1200 },
{ id: 'robin_1', savings: 50, cost: 100 },
{ id: 'robin_2', savings: 50, cost: 150 },
{ id: 'steve', savings: 100, cost: 1000 },
{ id: 'steve_1', savings: 50, cost: 550 },
{ id: 'steve_2', savings: 50, cost: 150 },
{ id: 'bob', savings: 1000, cost: 300 },
{ id: 'mark_1', savings: 50, cost: 150 }
];
const output = input.reduce((outObj, item) => {
const { savings, cost } = item;
const [mainKey, suffix] = item.id.split('_');
const subKey = suffix === undefined ? 'allTime' : 'today';
if (!outObj.hasOwnProperty(mainKey)) {
outObj[mainKey] = {
[subKey]: { savings, cost }
}
} else {
if (!outObj[mainKey].hasOwnProperty(subKey)) {
outObj[mainKey][subKey] = { savings, cost }
} else {
outObj[mainKey][subKey].savings = savings;
outObj[mainKey][subKey].cost = cost;
}
}
return outObj;
}, {})
//test
console.log(output);
При таком подходе вы не «жестко кодируете» свойства allTime
и today
в каждую запись выходного объекта; вместо этого вы динамически добавляете их только в том случае, если/где они необходимы (см. Примеры с bob
и mark
где добавляется только allTime
или today
)