我有一个包含对象的数组,如下所示。
b = {
"issues": [{
"fields": {
"status": {
"id": "200",
"name": "Backlog"
}
}
}, {
"fields": {
"status": {
"id": "202",
"name": "close"
}
}
}, {
"fields": {
"status": {
"id": "201",
"name": "close"
}
}
}]
};
我想计算有多少问题的状态为close
,有多少问题有backlog
。我想将计数保存在一个新的数组中,如下所示。
a = [
{Name: 'Backlog', count: 1},
{Name: 'close', count: 2}
];
我尝试了以下内容。
b.issues.forEach(function(i) {
var statusName = i.fields.status.name;
if (statusName in a.Name) {
a.count = +1;
} else {
a.push({
Name: statusName,
count: 1
});
}
});
然而,这似乎不起作用。我该如何实现呢?
答案 0 :(得分:20)
这是使用Array#reduce
的绝佳机会。该函数将采用一个按顺序应用于数组的所有元素的函数,并可用于累积值。我们可以使用它来累积具有各种计数的对象。
为了简化操作,我们只需{name: count, otherName: otherCount}
跟踪对象中的计数。对于每个元素,我们检查是否已有name
的条目。如果没有,请创建一个计数为0
的计数器。否则,递增计数。在reduce
之后,我们可以map
存储为keys of the object的密钥数组,采用问题中描述的格式。见下文。
var b = {
"issues": [{
"fields": {
"status": {
"id": "200",
"name": "Backlog"
}
}
}, {
"fields": {
"status": {
"id": "202",
"name": "close"
}
}
}, {
"fields": {
"status": {
"id": "201",
"name": "close"
}
}
}]
};
var counts = b.issues.reduce((p, c) => {
var name = c.fields.status.name;
if (!p.hasOwnProperty(name)) {
p[name] = 0;
}
p[name]++;
return p;
}, {});
console.log(counts);
var countsExtended = Object.keys(counts).map(k => {
return {name: k, count: counts[k]}; });
console.log(countsExtended);

.as-console-wrapper {
max-height: 100% !important;
}

备注强>
Array#reduce
不会修改原始数组。您可以轻松修改传递给reduce的函数,例如通过更改
来区分Backlog
和backlog
var name = c.fields.status.name;
到
var name = c.fields.status.name.toLowerCase();
例如,。还可以轻松实现更高级的功能。
答案 1 :(得分:2)
使用ES6箭头功能,您可以使用最少的语法
var b = {
"issues": [{
"fields": {
"status": {
"id": "200",
"name": "Backlog"
}
}
}, {
"fields": {
"status": {
"id": "202",
"name": "close"
}
}
}, {
"fields": {
"status": {
"id": "201",
"name": "close"
}
}
}]
};
var countOfBackLog = b.issues.filter(x => {
return x.fields.status.name === "Backlog"
}).length
var countOfClose = b.issues.filter(x => {
return x.fields.status.name === "close"
}).length
a =[{Name: 'Backlog', count : countOfBackLog}, {Name: 'close', count : countOfClose}]
有关箭头功能的更多信息here
答案 2 :(得分:1)
你可以这样写。它是动态的。
var a = {};
for(var key in b["issues"]){
if(!a.hasOwnProperty(b["issues"][key].fields.status.name)){
a[b["issues"][key].fields.status.name] = 1;
}else{
a[b["issues"][key].fields.status.name] = a[b["issues"][key].fields.status.name]+1;
}
}
var c = [];
for(var key1 in a){
c.push({
name : key1,
count : a[key1]
});
}
答案 3 :(得分:0)
这样的事情应该可以解决问题。只需迭代数据,保留2个计数器,每个类型的问题数量,最后创建所需的数据格式。在jsfiddle上试一试。
var b = {
"issues": [{
"fields": {
"status": {
"id": "200",
"name": "Backlog"
}
}
}, {
"fields": {
"status": {
"id": "202",
"name": "close"
}
}
}, {
"fields": {
"status": {
"id": "201",
"name": "close"
}
}
}]
};
var data = [];
for(var issue of b.issues){
var entryFound = false;
var tempObj = {
name: issue.fields.status.name,
count: 1
};
for(var item of data){
if(item.name === tempObj.name){
item.count++;
entryFound = true;
break;
}
}
if(!entryFound){
data.push(tempObj);
}
}
console.log(data);