I have an array
我有一个数组
data = [ '2016-12-12 pass [pass]',
'2016-12-12 pass [pass]',
'2016-12-12 fail [fail]',
'2016-12-13 fail [fail]',
'2016-12-14 fail [fail]',
'2016-12-14 pass [pass]',
'2016-12-14 pass [pass]',
'2016-12-15 pass [pass]',
'2016-12-16 fail [fail]' ]
I tried and thought a lot of ways to accomplish using various function but couldn't find out how to achieve this format:
我尝试了很多方法去实现各种各样的功能,但是没有找到实现这种格式的方法:
2016-12-12 pass:2 fail: 1
2016-12-13 pass:0 fail: 1
2016-12-14 pass:2 fail: 1
2016-12-15 pass:1 fail: 0
2016-12-16 pass:0 fail: 1
3 个解决方案
#1
1
You can use reduce()
and return array of objects.
可以使用reduce()和返回对象数组。
var data = [ '2016-12-12 pass [pass]',
'2016-12-12 pass [pass]',
'2016-12-12 fail [fail]',
'2016-12-13 fail [fail]',
'2016-12-14 fail [fail]',
'2016-12-14 pass [pass]',
'2016-12-14 pass [pass]',
'2016-12-15 pass [pass]',
'2016-12-16 fail [fail]' ]
var result = Object.values(data.reduce(function(r, e) {
var arr = e.split(' ')
if(!r[arr[0]]) r[arr[0]] = {date: arr[0], pass: 0, fail: 0}
r[arr[0]][arr[1]]++
return r;
}, {}))
console.log(JSON.stringify(result))
If you can't use Object.values()
you can just use map on object in the end.
如果不能使用object .values(),最后也可以使用map on object。
var data = [ '2016-12-12 pass [pass]',
'2016-12-12 pass [pass]',
'2016-12-12 fail [fail]',
'2016-12-13 fail [fail]',
'2016-12-14 fail [fail]',
'2016-12-14 pass [pass]',
'2016-12-14 pass [pass]',
'2016-12-15 pass [pass]',
'2016-12-16 fail [fail]' ]
var result = data.reduce(function(r, e) {
var arr = e.split(' ')
if(!r[arr[0]]) r[arr[0]] = {date: arr[0], pass: 0, fail: 0}
r[arr[0]][arr[1]]++
return r;
}, {})
result = Object.keys(result).map(e => result[e])
console.log(JSON.stringify(result))
#2
2
Here's one way:
这里有一个方法:
const data = [
'2016-12-12 pass [pass]',
'2016-12-12 pass [pass]',
'2016-12-12 fail [fail]',
'2016-12-13 fail [fail]',
'2016-12-14 fail [fail]',
'2016-12-14 pass [pass]',
'2016-12-14 pass [pass]',
'2016-12-15 pass [pass]',
'2016-12-16 fail [fail]',
];
const result = {};
data.forEach(item => {
const [date, passFail] = item.split(' ');
if (!(date in result)) {
result[date] = { pass: 0, fail: 0 };
}
result[date][passFail] += 1;
});
console.log(result);
As you can see in the output, this returns an object whose property names are dates and whose values are objects with the properties pass
and fail
.
正如您在输出中看到的,它返回一个对象,其属性名是日期,其值是具有属性传递和失败的对象。
Note that you could use reduce
instead of forEach
to save a line, but reduce
is sort of pointless if you're mutating the object anyway, so I've used forEach
for simplicity.
注意,您可以使用reduce而不是forEach来保存一行,但是如果您正在改变对象,那么reduce是没有意义的,所以我使用forEach来简化。
Note also that although in practice (i.e. in current JS engines) objects retain their properties' insertion order, strictly speaking JavaScript object properties are unordered. If you want to be strict about order, you'll need to use an array, in which case the simplest solution would be an after-the-fact transformation like the following:
还要注意,尽管在实践中(即在当前的JS引擎中)对象保留其属性的插入顺序,严格地说,JavaScript对象属性是无序的。如果你想严格要求顺序,你需要使用一个数组,在这种情况下,最简单的解决方案就是像下面这样的事后变换:
const result = {
"2016-12-12": { pass: 2, fail: 1 },
"2016-12-13": { pass: 0, fail: 1 },
"2016-12-14": { pass: 2, fail: 1 },
"2016-12-15": { pass: 1, fail: 0 },
"2016-12-16": { pass: 0, fail: 1 },
};
const resultArray = Object.keys(result).sort()
.map(key => [ key, result[key] ]);
console.log(resultArray);
#3
1
You can use reduce
to hash the dates into an object like this: (note the output is an object of object)
您可以使用reduce将日期散列到对象中(注意输出是对象的对象)
function group(arr) {
return arr.reduce(function(hash, e) { // for each element e in the array arr
var parts = e.split(' '); // split the element e by space
if(hash[parts[0]]) { // if the date (part 0) is already hashed
hash[parts[0]][parts[1]]++; // then increment the equivalent pass or fail (part 1)
}
else { // if not
hash[parts[0]] = {pass: 0, fail: 0}; // create a new object for the date
hash[parts[0]][parts[1]]++; // increment its pass or fail value
}
return hash;
}, {});
}
var array = ['2016-12-12 pass [pass]',
'2016-12-12 pass [pass]',
'2016-12-12 fail [fail]',
'2016-12-13 fail [fail]',
'2016-12-14 fail [fail]',
'2016-12-14 pass [pass]',
'2016-12-14 pass [pass]',
'2016-12-15 pass [pass]',
'2016-12-16 fail [fail]'
];
console.log(group(array));
#1
1
You can use reduce()
and return array of objects.
可以使用reduce()和返回对象数组。
var data = [ '2016-12-12 pass [pass]',
'2016-12-12 pass [pass]',
'2016-12-12 fail [fail]',
'2016-12-13 fail [fail]',
'2016-12-14 fail [fail]',
'2016-12-14 pass [pass]',
'2016-12-14 pass [pass]',
'2016-12-15 pass [pass]',
'2016-12-16 fail [fail]' ]
var result = Object.values(data.reduce(function(r, e) {
var arr = e.split(' ')
if(!r[arr[0]]) r[arr[0]] = {date: arr[0], pass: 0, fail: 0}
r[arr[0]][arr[1]]++
return r;
}, {}))
console.log(JSON.stringify(result))
If you can't use Object.values()
you can just use map on object in the end.
如果不能使用object .values(),最后也可以使用map on object。
var data = [ '2016-12-12 pass [pass]',
'2016-12-12 pass [pass]',
'2016-12-12 fail [fail]',
'2016-12-13 fail [fail]',
'2016-12-14 fail [fail]',
'2016-12-14 pass [pass]',
'2016-12-14 pass [pass]',
'2016-12-15 pass [pass]',
'2016-12-16 fail [fail]' ]
var result = data.reduce(function(r, e) {
var arr = e.split(' ')
if(!r[arr[0]]) r[arr[0]] = {date: arr[0], pass: 0, fail: 0}
r[arr[0]][arr[1]]++
return r;
}, {})
result = Object.keys(result).map(e => result[e])
console.log(JSON.stringify(result))
#2
2
Here's one way:
这里有一个方法:
const data = [
'2016-12-12 pass [pass]',
'2016-12-12 pass [pass]',
'2016-12-12 fail [fail]',
'2016-12-13 fail [fail]',
'2016-12-14 fail [fail]',
'2016-12-14 pass [pass]',
'2016-12-14 pass [pass]',
'2016-12-15 pass [pass]',
'2016-12-16 fail [fail]',
];
const result = {};
data.forEach(item => {
const [date, passFail] = item.split(' ');
if (!(date in result)) {
result[date] = { pass: 0, fail: 0 };
}
result[date][passFail] += 1;
});
console.log(result);
As you can see in the output, this returns an object whose property names are dates and whose values are objects with the properties pass
and fail
.
正如您在输出中看到的,它返回一个对象,其属性名是日期,其值是具有属性传递和失败的对象。
Note that you could use reduce
instead of forEach
to save a line, but reduce
is sort of pointless if you're mutating the object anyway, so I've used forEach
for simplicity.
注意,您可以使用reduce而不是forEach来保存一行,但是如果您正在改变对象,那么reduce是没有意义的,所以我使用forEach来简化。
Note also that although in practice (i.e. in current JS engines) objects retain their properties' insertion order, strictly speaking JavaScript object properties are unordered. If you want to be strict about order, you'll need to use an array, in which case the simplest solution would be an after-the-fact transformation like the following:
还要注意,尽管在实践中(即在当前的JS引擎中)对象保留其属性的插入顺序,严格地说,JavaScript对象属性是无序的。如果你想严格要求顺序,你需要使用一个数组,在这种情况下,最简单的解决方案就是像下面这样的事后变换:
const result = {
"2016-12-12": { pass: 2, fail: 1 },
"2016-12-13": { pass: 0, fail: 1 },
"2016-12-14": { pass: 2, fail: 1 },
"2016-12-15": { pass: 1, fail: 0 },
"2016-12-16": { pass: 0, fail: 1 },
};
const resultArray = Object.keys(result).sort()
.map(key => [ key, result[key] ]);
console.log(resultArray);
#3
1
You can use reduce
to hash the dates into an object like this: (note the output is an object of object)
您可以使用reduce将日期散列到对象中(注意输出是对象的对象)
function group(arr) {
return arr.reduce(function(hash, e) { // for each element e in the array arr
var parts = e.split(' '); // split the element e by space
if(hash[parts[0]]) { // if the date (part 0) is already hashed
hash[parts[0]][parts[1]]++; // then increment the equivalent pass or fail (part 1)
}
else { // if not
hash[parts[0]] = {pass: 0, fail: 0}; // create a new object for the date
hash[parts[0]][parts[1]]++; // increment its pass or fail value
}
return hash;
}, {});
}
var array = ['2016-12-12 pass [pass]',
'2016-12-12 pass [pass]',
'2016-12-12 fail [fail]',
'2016-12-13 fail [fail]',
'2016-12-14 fail [fail]',
'2016-12-14 pass [pass]',
'2016-12-14 pass [pass]',
'2016-12-15 pass [pass]',
'2016-12-16 fail [fail]'
];
console.log(group(array));