Javascript 如何对对象数组中的多个属性值进行计数和分组?
我有一个对象数组:Javascript 如何对对象数组中的多个属性值进行计数和分组?,javascript,arrays,object,Javascript,Arrays,Object,我有一个对象数组: [ {'year': 2019, 'a_academic': 3, 'f_security': 4, ..., 'k_services': 3}, {'year': 2019, 'a_academic': 2, 'f_security': 2, ..., 'k_services': 4}, {'year': 2019, 'a_academic': 3, 'f_security': 3, ..., 'k_services': 1}, ... {'year':
[
{'year': 2019, 'a_academic': 3, 'f_security': 4, ..., 'k_services': 3},
{'year': 2019, 'a_academic': 2, 'f_security': 2, ..., 'k_services': 4},
{'year': 2019, 'a_academic': 3, 'f_security': 3, ..., 'k_services': 1},
...
{'year': 2019, 'a_academic': 3, 'f_security': 3, ..., 'k_services': 3},
]
如何计算多个属性值,然后将其分组,并将其保存在新对象中,例如:
{
'a_academic': {
4: 0,
3: 3,
2: 1,
1: 0
},
'f_security': {
4: 1,
3: 2,
2: 1,
1: 0
},
...,
'k_services': {
4: 1,
3: 2,
2: 0,
1: 1
}
}
我可以使用reduce和手动访问密钥来完成此操作,但仅针对一个属性:
let count = array.reduce((res, cur) => {
res[cur.a_academic] = res[cur.a_academic] ? res[cur.a_academic] + 1 : 1;
return res;
}, {});
console.log(count);
结果:
{
3: 3,
2: 1
}
如何有效地实现此功能,使其在不手动访问的情况下适用于所有其他属性?您可以定义一个要计数的键数组,然后使用
reduce
方法在对象上嵌套forEach
循环。条目
并计算每个已定义键的出现值
const数据=[
{'year':2019,'a_academic':3,'f_security':4,'k_services':3},
{'year':2019,'a_academic':2,'f_security':2,'k_services':4},
{'year':2019,'a_academic':3,'f_security':3,'k_services':1},
{'year':2019,'a_academic':3,'f_security':3,'k_services':3},
]
const-props=['a_-academical'、'f_-security'、'k_-services']
常数结果=数据减少((r,e)=>{
Object.entries(e.forEach)([k,v])=>{
if(道具包括(k)){
如果(!r[k])r[k]={}
r[k][v]=(r[k][v]| | 0)+1
}
})
返回r;
}, {})
console.log(result)
您需要一个嵌套的分组,方法是从对象中省略year
var data=[{年份:2019,a_学术:3,f_安全:4,k_服务:3},{年份:2019,a_学术:2,f_安全:2,k_服务:4},{年份:2019,a_学术:3,f_安全:3,k_服务:1},{年份:2019,a_学术:3,f_安全:3,k_服务:3}],
分组=数据。减少((r,{year,…o})=>{
Object.entries(o.forEach)([k,v])=>{
r[k]=r[k]|{};
r[k][v]=(r[k][v]| | 0)+1;
});
返回r;
}, {});
控制台日志(分组)代码>您所做的是使用cur.academic
的值,而不是键名。为了更好地解释这一点,请考虑这个
const obj = { alpha: 20, beta: 30, gamma: 40 };
console.log(obj['alpha']); // outputs 20
你能做的是:
const array = [
{'year': 2019, 'a_academic': 3, 'f_security': 4, 'k_services': 3},
{'year': 2019, 'a_academic': 2, 'f_security': 2, 'k_services': 4},
{'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 1},
{'year': 2019, 'a_academic': 3, 'f_security': 3, 'k_services': 3},
];
const excludedKeys = ['year'];
let count = array.reduce((res, curr) => {
// Select the keys you are going to use and exclude the ones you won't
const keys = Object.keys(curr).filter(key => !excludedKeys.includes(key));
keys.forEach(key => {
res[key] = res[key] ? res[key] + 1 : 1;
});
return res;
}, {});
console.log(count);
您可以从一个对象(不包括year
)中获取关键点,然后将每个关键点映射到计数数组。例如,a_学术
具有映射到[0,0,1,3,0]
的值数组[3,2,3,3]
。使用此total
数组,您可以使用Object.assign()
将其索引分配给一个对象,您可以将其用于每个组,如下所示:
const arr=[
{'year':2019,'a_academic':3,'f_security':4,'k_services':3},
{'year':2019,'a_academic':2,'f_security':2,'k_services':4},
{'year':2019,'a_academic':3,'f_security':3,'k_services':1},
{'year':2019,'a_academic':3,'f_security':3,'k_services':3},
];
const groupArr=([{year,…first},…arr])=>{
常量=Object.entries(第一个);
const gr=ent.map(([key,v])=>v,…arr.map(o=>o[key]);
const maxN=Math.max(…gr.flat());
const minN=Math.min(…gr.flat());
常量总计=gr.map(arr=>
arr.reduce((tally,n)=>(tally[n]+,tally),数组(minN).concat(数组(maxN).fill(0)))
);
返回Object.assign({},{ent.map(([k],i)=>({[k]:Object.assign({},total[i]));
}
console.log(groupArr(arr))代码>只需添加对象。键
循环逻辑以动态访问键
const数组=[
{年份:2019,a_学术:3,f_安全:4,k_服务:3},
{年份:2019,a_学术:2,f_安全:2,k_服务:4},
{年份:2019,a_学术:3,f_安全:3,k_服务:1},
{年份:2019,a_学术:3,f_安全:3,k_服务:3}
];
let count=数组。reduce((res,cur)=>{
Object.keys(cur)
.filter(key=>key.includes(“”))
.forEach(键=>{
const obj=res[key]|{};
res[key]={
…obj,
[cur[key]]:(obj[cur[key]| | 0)+1
};
});
返回res;
}, {});
控制台日志(计数)代码>