I have an array with objects, like the following.
我有一个包含对象的数组,如下所示。
b = {
"issues": [{
"fields": {
"status": {
"id": "200",
"name": "Backlog"
}
}
}, {
"fields": {
"status": {
"id": "202",
"name": "close"
}
}
}, {
"fields": {
"status": {
"id": "201",
"name": "close"
}
}
}]
};
I want to count how many issues have status close
, and how many have backlog
. I'd like to save the count in a new array as follows.
我想计算有多少问题的状态接近,有多少有积压。我想将计数保存在一个新数组中,如下所示。
a = [
{Name: 'Backlog', count: 1},
{Name: 'close', count: 2}
];
I have tried the following.
我尝试了以下内容。
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
});
}
});
That however doesn't seem to be working. How should I implement this?
然而,这似乎不起作用。我该如何实现呢?
4 个解决方案
#1
12
This is a perfect opportunity to use Array#reduce
. That function will take a function that is applied to all elements of the array in order and can be used to accumulate a value. We can use it to accumulate an object with the various counts in it.
这是使用Array#reduce的绝佳机会。该函数将采用一个按顺序应用于数组的所有元素的函数,并可用于累积值。我们可以使用它来累积具有各种计数的对象。
To make things easy, we track the counts in an object as simply {name: count, otherName: otherCount}
. For every element, we check if we already have an entry for name
. If not, create one with count 0
. Otherwise, increment the count. After the reduce
, we can map
the array of keys, stored as keys of the object, to be in the format described in the question. See below.
为了简单起见,我们只是简单地跟踪对象中的计数{name:count,otherName:otherCount}。对于每个元素,我们检查是否已有名称条目。如果不是,请创建一个计数为0.否则,递增计数。在reduce之后,我们可以将存储为对象的键的键数组映射到问题中描述的格式。见下文。
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;
}
Notes.
笔记。
-
Array#reduce
does not modify the original array. - Array#reduce不会修改原始数组。
-
You can easily modify the function passed to reduce to for example not distinguish between
Backlog
andbacklog
by changing您可以轻松修改传递给reduce的函数,例如通过更改来区分Backlog和backlog
var name = c.fields.status.name;
into
成
var name = c.fields.status.name.toLowerCase();
for example. More advanced functionality can also easily be implemented.
例如。还可以轻松实现更高级的功能。
#2
1
Using ES6 Arrow functions you can do it with minimum syntax
使用ES6 Arrow功能,您可以使用最少的语法执行此操作
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}]
More about arrow functions here
更多关于箭头功能的信息
#3
0
You can write like this. It is dynamic.
你可以这样写。这是动态的。
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]
});
}
#4
0
Something like this should do the trick. Simply iterate over your data, keep 2 counters with the number of each type of issue, and create the data format you want in the end. Try it live on jsfiddle.
这样的事情应该可以解决问题。只需迭代您的数据,保留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);
#1
12
This is a perfect opportunity to use Array#reduce
. That function will take a function that is applied to all elements of the array in order and can be used to accumulate a value. We can use it to accumulate an object with the various counts in it.
这是使用Array#reduce的绝佳机会。该函数将采用一个按顺序应用于数组的所有元素的函数,并可用于累积值。我们可以使用它来累积具有各种计数的对象。
To make things easy, we track the counts in an object as simply {name: count, otherName: otherCount}
. For every element, we check if we already have an entry for name
. If not, create one with count 0
. Otherwise, increment the count. After the reduce
, we can map
the array of keys, stored as keys of the object, to be in the format described in the question. See below.
为了简单起见,我们只是简单地跟踪对象中的计数{name:count,otherName:otherCount}。对于每个元素,我们检查是否已有名称条目。如果不是,请创建一个计数为0.否则,递增计数。在reduce之后,我们可以将存储为对象的键的键数组映射到问题中描述的格式。见下文。
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;
}
Notes.
笔记。
-
Array#reduce
does not modify the original array. - Array#reduce不会修改原始数组。
-
You can easily modify the function passed to reduce to for example not distinguish between
Backlog
andbacklog
by changing您可以轻松修改传递给reduce的函数,例如通过更改来区分Backlog和backlog
var name = c.fields.status.name;
into
成
var name = c.fields.status.name.toLowerCase();
for example. More advanced functionality can also easily be implemented.
例如。还可以轻松实现更高级的功能。
#2
1
Using ES6 Arrow functions you can do it with minimum syntax
使用ES6 Arrow功能,您可以使用最少的语法执行此操作
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}]
More about arrow functions here
更多关于箭头功能的信息
#3
0
You can write like this. It is dynamic.
你可以这样写。这是动态的。
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]
});
}
#4
0
Something like this should do the trick. Simply iterate over your data, keep 2 counters with the number of each type of issue, and create the data format you want in the end. Try it live on jsfiddle.
这样的事情应该可以解决问题。只需迭代您的数据,保留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);