英文:
Sum multiple keys and merge to one object based off a specific key
问题
以下是代码部分的翻译:
const total_sum_data = (arr, key, value) => {
const map = new Map();
for (const obj of arr) {
const currSum = map.get(obj[key]) || 0;
map.set(obj[key], currSum + obj[value]);
}
const res = Array.from(map, ([k, v]) => ({ [key]: k, [value]: v }));
return res;
};
请注意,代码部分已经在你的消息中提供,不需要再次翻译。如果你需要有关代码的任何解释或进一步的帮助,请随时提问。
英文:
Let's say I have an array of objects and want to group these by a specified key: 'name', and sum all of their values into one object:
[
{
name: "test1",
value1: 100,
value2: 100,
value3: 100
},
{
name: "test1",
value1: 100,
value2: 100,
value3: 100
},
{
name: "test2",
value1: 200,
value2: 100,
value3: 100
},
{
name: "test2",
value1: 200,
value2: 100,
value3: 100
},
{
name: "test3",
value1: 100,
value2: 100,
value3: 100
}
]
And the result I want would have this structure:
[
{
name: "test1",
value1: 200,
value2: 200,
value3: 200
},
{
name: "test2",
value1: 400,
value2: 200,
value3: 200
},
{
name: "test3",
value1: 100,
value2: 100,
value3: 100
}
]
How would I go about doing this? I can currently get the sum of one key by using this method:
const total_sum_data = (arr, key, value) => {
const map = new Map();
for (const obj of arr) {
const currSum = map.get(obj[key]) || 0;
map.set(obj[key], currSum + obj[value]);
}
const res = Array.from(map, ([k, v]) => ({ [key]: k, [value]: v }));
return res;
};
But not sure how to merge the results into one object with the specified key.
答案1
得分: 1
你可以使用数组的reduce方法将数组减少为累加器对象 (a
),通过将每个对象解构为其 name
和 values
,然后在累加器对象中对每个 name
的所有值求和。然后,你只需要检索累加器的对象值以获得最终结果:
const result = Object.values(data.reduce((a, {name, ...values}) => {
a[name] ??= { name };
Object.entries(values).forEach(([key, value]) => {
a[name][key] ??= 0;
a[name][key] += value;
});
return a;
} , {}));
这个解决方案的时间复杂度为 O(n)。它会很好地处理添加新值(value4
,value5
,...)和不是所有对象中都存在所有值的情况。
完整的代码段如下:
const data = [{
name: "test1",
value1: 100,
value2: 100,
value3: 100
}, {
name: "test1",
value1: 100,
value2: 100,
value3: 100
}, {
name: "test2",
value1: 200,
value2: 100,
value3: 100
}, {
name: "test2",
value1: 200,
value2: 100,
value3: 100
}, {
name: "test3",
value1: 100,
value2: 100,
value3: 100
}];
const result = Object.values(data.reduce((a, {name, ...values}) => {
a[name] ??= { name };
Object.entries(values).forEach(([key, value]) => {
a[name][key] ??= 0;
a[name][key] += value;
});
return a;
} , {}));
console.log(result);
英文:
You can reduce the array to an accumulator object (a
) by destructuring each object into its name
and values
, and summing all the values for each name in the accumulator object. Then you just need to retrieve the accumulator's object values to get to your final result:
const result = Object.values(data.reduce((a, {name, ...values}) => {
a[name] ??= { name };
Object.entries(values).forEach(([key, value]) => {
a[name][key] ??= 0;
a[name][key] += value;
});
return a;
} , {}));
This solution has a time complexity of O(n). It will gracefully handle cases where new values are added (value4
, value5
, ...), and cases where not all values are present in all objects.
Complete snippet:
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
const data = [{
name: "test1",
value1: 100,
value2: 100,
value3: 100
}, {
name: "test1",
value1: 100,
value2: 100,
value3: 100
}, {
name: "test2",
value1: 200,
value2: 100,
value3: 100
}, {
name: "test2",
value1: 200,
value2: 100,
value3: 100
}, {
name: "test3",
value1: 100,
value2: 100,
value3: 100
}];
const result = Object.values(data.reduce((a, {name, ...values}) => {
a[name] ??= { name };
Object.entries(values).forEach(([key, value]) => {
a[name][key] ??= 0;
a[name][key] += value;
});
return a;
} , {}));
console.log(result);
<!-- end snippet -->
答案2
得分: 0
以下是代码的翻译部分:
例如:
const total_sum_data = (arr, key) => {
const map = new Map();
for (const obj of arr) {
const groupKey = obj[key];
if (!map.has(groupKey)) {
map.set(groupKey, { [key]: groupKey });
}
const currObj = map.get(groupKey);
Object.keys(obj).forEach(k => {
if (k !== key) {
currObj[k] = (currObj[k] || 0) + obj[k];
}
});
}
return Array.from(map.values());
};
console.log(total_sum_data(arr,"name"));
英文:
For example:
const total_sum_data = (arr, key) => {
const map = new Map();
for (const obj of arr) {
const groupKey = obj[key];
if (!map.has(groupKey)) {
map.set(groupKey, { [key]: groupKey });
}
const currObj = map.get(groupKey);
Object.keys(obj).forEach(k => {
if (k !== key) {
currObj[k] = (currObj[k] || 0) + obj[k];
}
});
}
return Array.from(map.values());
};
console.log(total_sum_data(arr,"name"));
答案3
得分: 0
使用 Map 和 reduce 可以实现这个功能。
在使用 Map 的情况下,代码如下:
const map = new Map();
for (const item of data) {
if (!map.has(item.name)) {
map.set(item.name, {
name: item.name,
value1: item.value1,
value2: item.value2,
value3: item.value3
});
} else {
map.get(item.name).value1 += item.value1;
map.get(item.name).value2 += item.value2;
map.get(item.name).value3 += item.value3;
}
}
console.log(Array.from(map.values()));
而在使用 reduce 的情况下,可以这样实现:
const groupedSum = data.reduce((acc, curr) => {
const objIndex = acc.findIndex(obj => obj.name === curr.name);
if (objIndex === -1) {
acc.push({ name: curr.name, value1: curr.value1, value2: curr.value2, value3: curr.value3 });
} else {
acc[objIndex].value1 += curr.value1;
acc[objIndex].value2 += curr.value2;
acc[objIndex].value3 += curr.value3;
}
return acc;
}, []);
console.log(groupedSum);
希望这些对你有帮助。
英文:
It can be achieved using Map and reduce.
while using Map here is a code:
const map = new Map();
for (const item of data) {
if (!map.has(item.name)) {
map.set(item.name, {
name: item.name,
value1: item.value1,
value2: item.value2,
value3: item.value3
});
} else {
map.get(item.name).value1 += item.value1;
map.get(item.name).value2 += item.value2;
map.get(item.name).value3 += item.value3;
}
}
console.log(Array.from(map.values()));
and while using reduce it can be done like this
const groupedSum = data.reduce((acc, curr) => {
const objIndex = acc.findIndex(obj => obj.name === curr.name);
if (objIndex === -1) {
acc.push({ name: curr.name, value1: curr.value1, value2: curr.value2, value3: curr.value3 });
} else {
acc[objIndex].value1 += curr.value1;
acc[objIndex].value2 += curr.value2;
acc[objIndex].value3 += curr.value3;
}
return acc;
}, []);
console.log(groupedSum);
答案4
得分: 0
希望以下逻辑能帮助您:
let array = [
{
name: "test1",
value1: 100,
value2: 100,
value3: 100
},
{
name: "test1",
value1: 100,
value2: 100,
value3: 100
},
{
name: "test2",
value1: 200,
value2: 100,
value3: 100
},
{
name: "test2",
value1: 200,
value2: 100,
value3: 100
},
{
name: "test3",
value1: 100,
value2: 100,
value3: 100
},
]
let reduceArr = array.reduce((prev, next) =>{
if (next.name in prev) {
prev[next.name].value1 += next.value1;
prev[next.name].value2 += next.value2;
prev[next.name].value3 += next.value3;
} else {
prev[next.name] = next;
}
return prev;
}, {});
let result = Object.values(reduceArr);
console.log(result)
请注意,我已经移除了HTML标记以及HTML注释,只保留了JavaScript代码。
英文:
Hope below logic will help you
<!-- begin snippet: js hide: false console: true babel: false -->
<!-- language: lang-js -->
let array = [
{
name: "test1",
value1: 100,
value2: 100,
value3: 100
},
{
name: "test1",
value1: 100,
value2: 100,
value3: 100
},
{
name: "test2",
value1: 200,
value2: 100,
value3: 100
},
{
name: "test2",
value1: 200,
value2: 100,
value3: 100
},
{
name: "test3",
value1: 100,
value2: 100,
value3: 100
},
]
let reduceArr = array.reduce((prev, next) =>{
if (next.name in prev) {
prev[next.name].value1 += next.value1;
prev[next.name].value2 += next.value2;
prev[next.name].value3 += next.value3;
} else {
prev[next.name] = next;
}
return prev;
}, {});
let result = Object.values(reduceArr);
console.log(result)
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论