javascript - 将总和添加到对象中的每个元素并返回 Javascript 中的前 N 个键/值对
问题描述
我有一个键/值对的对象数组,其中值是另一组键/值对,其中所有值都是数字。我想总结每个键的所有值,然后为每个键添加一个具有聚合总和的新元素。一旦我有了它,我希望能够根据聚合的总和值选择对象数组中的前 5 个主键。
我的数据(对象)看起来像这样
{
"Napkins":{
"N/A":200,
"No supply":100,
"More than 1 wk":150,
"1 week or less":50
},
"Plates":{
"N/A":800
},
"Forks":{
"N/A":100,
"No supply":100,
"More than 1 wk":50,
"1 week or less":50
},
"Knives":{
"N/A":300,
"No supply":100
}
}
我希望能够添加一个total
值来对每个主外键的值求和,以便我的最终对象看起来像这样:
{
"Napkins":{
"N/A":200,
"No supply":100,
"More than 1 wk":150,
"1 week or less":50,
"total":500
},
"Plates":{
"N/A":800,
"total":800
},
"Forks":{
"N/A":100,
"No supply":100,
"More than 1 wk":50,
"1 week or less":50,
"total":300
},
"Knives":{
"N/A":300,
"No supply":100,
"total":400
}
}
一旦我有了它,我希望能够轻松地对数组进行排序total
并按前 5 个或任意数字n对其进行切片,以仅返回这n 个项目,以便我可以遍历它们并为每个项目创建一个 d3 可视化前n项。我唯一的问题是获得最重要的项目所需的最终数组。
编辑:我能够编写一个嵌套循环来添加一个total
字段。不确定是否有更好的方法来做到这一点,但现在希望了解访问切片和访问具有前 5 个total
值的键/值元素的最佳方法。这是我用于循环原始对象的代码:
for (const item of Object.values(processed_data)){
let sum = Object.values(item).reduce((a,b) => a+b, 0);
item.total = sum;
}
解决方案
由于对象数据结构,不可能像这样对值进行排序。但是,我能够将条目数限制N
在以下代码中:
const data = {
"Napkins": {
"N/A": 200,
"No supply": 100,
"More than 1 wk": 150,
"1 week or less": 50
},
"Plates": {
"N/A": 800
},
"Forks": {
"N/A": 100,
"No supply": 100,
"More than 1 wk": 50,
"1 week or less": 50
},
"Knives": {
"N/A": 300,
"No supply": 100
}
};
const getTopN = 3;
Object.values(data).forEach(reasons => {
// Alternatively, d3.sum(Object.values(reasons)) also works
reasons.total = Object.values(reasons).reduce((sum, v) => sum + v, 0);
}, {});
// Get the value from the N^th threshold
const threshold = Object.values(data)
.map(reasons => reasons.total)
.sort()
.reverse()[getTopN - 1];
const topN = Object.entries(data)
.filter(([type, reasons]) => reasons.total >= threshold)
.reduce((obj, [type, reasons]) => {
obj[type] = reasons;
return obj;
}, {});
console.log(topN);
或者,您可以更改数据结构:
const data = {
"Napkins": {
"N/A": 200,
"No supply": 100,
"More than 1 wk": 150,
"1 week or less": 50
},
"Plates": {
"N/A": 800
},
"Forks": {
"N/A": 100,
"No supply": 100,
"More than 1 wk": 50,
"1 week or less": 50
},
"Knives": {
"N/A": 300,
"No supply": 100
}
};
const getTopN = 3;
const arrayData = Object.entries(data)
.map(([item, reasons]) => ({
item,
total: Object.values(reasons).reduce((sum, v) => sum + v, 0),
reasons
}))
.sort((a, b) => b.total - a.total)
.slice(0, getTopN);
console.log(arrayData);
推荐阅读
- git - 如何在窗口更改后保存提交消息
- laravel - Foreach 无法使用我的管理仪表板“未定义变量:用户”laravel
- ruby - 执行异步作业后,如何将实际作业包裹在基类中的 worker_monitor 周围?
- swift - XCUITest 到后台应用程序返回错误的 XCUIApplication.State
- firebase - 在 TabBarView 中加载 Firestore 数据
- python-3.x - 如何根据数据框熊猫的唯一首字母构建新列
- python - 如何从具有自定义特征的 span 标签中获取数据?(美人汤)
- r - 如何使用 rmarkdown 添加引用
- java - 正确调整空元素的大小
- django - Django:NoReverseMatch - 没有找到带有参数'('','')'的''的反向