如何通过特定对象键对数组中的值求和?
Posted
技术标签:
【中文标题】如何通过特定对象键对数组中的值求和?【英文标题】:How to sum values in array by specific object key? 【发布时间】:2020-06-14 21:45:45 【问题描述】:我有一个 js 对象数组,如下所示:
var objArr = [
"Country": "US", "City": "MyCity1", "2017-07-12": "1", "2017-07-13": "2",
"Country": "US", "City": "MyCity2", "2017-07-12": "2", "2017-07-13": "2",
"Country": "CN", "City": "MyCity1", "2017-07-12": "5", "2017-07-13": "7",
"Country": "CN", "City": "MyCity2", "2017-07-12": "5", "2017-07-13": "7"
]
我想创建一个新数组,其中国家/地区是唯一的,但日期也应该相加。
"Country": "US", "2017-07-12": "3", "2017-07-13": "4",
"Country": "CN", "2017-07-12": "10", "2017-07-13": "14"
^^^^ ^^^^ ^^^^
我很难理解它。 我必须先过滤,以某种方式减少它,重新映射它,......我不知道开始吗? 任何帮助将不胜感激,谢谢!
【问题讨论】:
哦,在这种情况下,您只需按国家/地区对条目进行分组,然后将相同属性的值相加 这能回答你的问题吗? Most efficient method to groupby on an array of objects 特别是,您可以查看Scott Sauyet's answer,它提供了一种更灵活的方法。其他一些还展示了如何分组和转换。 【参考方案1】:对数组使用一个forEach
并使用forEach
遍历每个对象的日期键,并使用唯一键为Country
和累积值构建一个res
对象。
使用 Object.values
的 res 从 res 对象中获取数组。
更新:修复以确保始终使用一种日期类型,即 number
。
var objArr = [
Country: "US", City: "MyCity1", "2017-07-12": "1", "2017-07-13": "2" ,
Country: "US", City: "MyCity2", "2017-07-12": "2", "2017-07-13": "2" ,
Country: "CN", City: "MyCity1", "2017-07-12": "5", "2017-07-13": "7" ,
Country: "CN", City: "MyCity2", "2017-07-12": "5", "2017-07-13": "7"
];
const update = data =>
const res = ;
data.forEach(( Country, City, ...dates ) =>
const item = res[Country] || Country ;
Object.keys(dates).forEach(date =>
item[date] = (item[date] || 0) + Number(dates[date]);
);
res[Country] = ...item ;
);
return Object.values(res);
;
console.log(update(objArr));
【讨论】:
我的一些结果是字符串,有些是整数。这是正常的吗? ` 国家:“中国”3/1/20:79826 3/2/20:80026 1:国家:“泰国”2020 年 1 月 22 日:“2” 2020 年 1 月 23 日:“3” @Jan,哦,我明白了。我认为最好有相同类型的物品。在这里我认为数字更好。我更新了答案以确保始终有数字。【参考方案2】:使用Array.reduce
,检查当前国家的对象是否存在,如果存在,循环通过Object.keys
更新值,如果不存在,推送一个新的:
编辑:如果你不想要 City,你可以解构它 City, ...curr
var objArr = [
Country: "US", City: "MyCity1", "2017-07-12": "1", "2017-07-13": "2" ,
Country: "US", City: "MyCity2", "2017-07-12": "2", "2017-07-13": "2" ,
Country: "CN", City: "MyCity1", "2017-07-12": "5", "2017-07-13": "7" ,
Country: "CN", City: "MyCity2", "2017-07-12": "5", "2017-07-13": "7"
];
var result = objArr.reduce((acc, City, ...curr) =>
const ndx = acc.findIndex(e => e.Country === curr.Country);
if (ndx > -1)
const [country, ...keys] = Object.keys(curr);
keys.forEach(k =>
acc[ndx][k] = +acc[ndx][k] + +curr[k];
);
else
acc.push(curr);
return acc;
, []);
console.log(result);
【讨论】:
Op 不想在结果中显示城市【参考方案3】:您可以使用reduce()
创建一个对象来对元素进行分组,然后使用Object.values
var objArr = [
"Country": "US", "City": "MyCity1", "2017-07-12": "1", "2017-07-13": "2",
"Country": "US", "City": "MyCity2", "2017-07-12": "2", "2017-07-13": "2",
"Country": "CN", "City": "MyCity1", "2017-07-12": "5", "2017-07-13": "7",
"Country": "CN", "City": "MyCity2", "2017-07-12": "5", "2017-07-13": "7"
]
let keys = ["2017-07-12", "2017-07-13"];
const res = Object.values(objArr.reduce((ac, a) =>
if(!ac[a.Country])
ac[a.Country] = Country: a.Country;
keys.forEach(k =>
ac[a.Country][k] = (ac[a.Country][k] || 0) + Number(a[k]);
)
return ac;
, ))
console.log(res)
【讨论】:
以上是关于如何通过特定对象键对数组中的值求和?的主要内容,如果未能解决你的问题,请参考以下文章