聚合 JavaScript 中的对象数组
Aggregate an array of objects in JavaScript
我有一个包含布尔字段 X 的对象数组。[{..., x: true, y: 3, ...]
我需要聚合这个数组,为了得到一个值,true
(或false
),如果全部值x
对应true
(或false
),否则undefined
...和y
的总和...
是否可以使用 reduce
Array 函数,groupby by underscorejs,或其他用于此目的的函数?
例如:
[
{a:'titi', x: true, y: 3},
{a:'toto', x: false, y: 6}
]
结果
{x: undefined, y: 9}
尽管您可以将其硬塞到 reduce
调用中(因为任何数组操作都可以硬塞到 reduce
中),但这样做没有任何好处。只需使用一个循环:
const result = {x: null, y: 0};
for (const entry of array) {
if (result.x === null) {
result.x = entry.x;
} else if (result.x !== entry.x) {
result.x = undefined;
}
result.y += entry.y;
}
实例:
function check(array) {
const result = {x: null, y: 0};
for (const entry of array) {
if (result.x === null) {
result.x = entry.x;
} else if (result.x !== entry.x) {
result.x = undefined;
}
result.y += entry.y;
}
console.log(result);
}
check([
{a:'titi', x: true, y: 3},
{a:'toto', x: false, y: 6}
]);
console.log("---");
check([
{a:'titi', x: true, y: 3},
{a:'toto', x: true, y: 6}
]);
console.log("---");
check([
{a:'titi', x: false, y: 3},
{a:'toto', x: false, y: 6}
]);
console.log("---");
但是,如果您愿意,您可以通过始终返回相同的对象将其硬塞进 reduce
:
const result = array.reduce((obj, entry) => {
if (obj.x === null) {
obj.x = entry.x;
} else if (obj.x !== entry.x) {
obj.x = undefined;
}
obj.y += entry.y;
return obj;
}, {x: null, y: 0});
实例:
function check(array) {
const result = array.reduce((obj, entry) => {
if (obj.x === null) {
obj.x = entry.x;
} else if (obj.x !== entry.x) {
obj.x = undefined;
}
obj.y += entry.y;
return obj;
}, {x: null, y: 0});
console.log(result);
}
check([
{a:'titi', x: true, y: 3},
{a:'toto', x: false, y: 6}
]);
console.log("---");
check([
{a:'titi', x: true, y: 3},
{a:'toto', x: true, y: 6}
]);
console.log("---");
check([
{a:'titi', x: false, y: 3},
{a:'toto', x: false, y: 6}
]);
console.log("---");
但是,如果您想要一个 reduce
解决方案并且您不介意创建一堆临时的一次性对象,请查看 .简单明了,99.9% 的时候,你不关心临时对象的创建。
我使用 reduce
想出了这个解决方案。似乎有点 hacky,但它应该完成这项工作。在减少数组时,它确定每个 x 值是否相等,然后相应地设置减少对象的 x 值。
let reduced = arr.reduce((acc, curr) => {
acc.x &= acc.x_init === curr.x;
acc.y += curr.y;
}, {x_init: arr[0].x, x: true, y: 0});
reduced.x = reduced.x ? reduced.x_init : undefined;
delete reduced.x_init;
这对于 reduce 来说非常简单:
.reduce((a, b) => ({
x: a.x == b.x ? a.x : undefined,
y: a.y + b.y
}))
实例:
var input = [
{a:'titi', x: true, y: 3},
{a:'toto', x: false, y: 6}
];
console.log(input.reduce((a, b) => ({
x: a.x == b.x ? a.x : undefined,
y: a.y + b.y
})));
感谢@Adassko,我的变体有点长:
[
{a:'titi', x: false, y: 3},
{a:'toto', x: false, y: 6}
]
.reduce((a, b, i) => ({
x : a.x === b.x || i == 0 ? b.x : undefined,
y : a.y + b.y
}))
我有一个包含布尔字段 X 的对象数组。[{..., x: true, y: 3, ...]
我需要聚合这个数组,为了得到一个值,true
(或false
),如果全部值x
对应true
(或false
),否则undefined
...和y
的总和...
是否可以使用 reduce
Array 函数,groupby by underscorejs,或其他用于此目的的函数?
例如:
[
{a:'titi', x: true, y: 3},
{a:'toto', x: false, y: 6}
]
结果
{x: undefined, y: 9}
尽管您可以将其硬塞到 reduce
调用中(因为任何数组操作都可以硬塞到 reduce
中),但这样做没有任何好处。只需使用一个循环:
const result = {x: null, y: 0};
for (const entry of array) {
if (result.x === null) {
result.x = entry.x;
} else if (result.x !== entry.x) {
result.x = undefined;
}
result.y += entry.y;
}
实例:
function check(array) {
const result = {x: null, y: 0};
for (const entry of array) {
if (result.x === null) {
result.x = entry.x;
} else if (result.x !== entry.x) {
result.x = undefined;
}
result.y += entry.y;
}
console.log(result);
}
check([
{a:'titi', x: true, y: 3},
{a:'toto', x: false, y: 6}
]);
console.log("---");
check([
{a:'titi', x: true, y: 3},
{a:'toto', x: true, y: 6}
]);
console.log("---");
check([
{a:'titi', x: false, y: 3},
{a:'toto', x: false, y: 6}
]);
console.log("---");
但是,如果您愿意,您可以通过始终返回相同的对象将其硬塞进 reduce
:
const result = array.reduce((obj, entry) => {
if (obj.x === null) {
obj.x = entry.x;
} else if (obj.x !== entry.x) {
obj.x = undefined;
}
obj.y += entry.y;
return obj;
}, {x: null, y: 0});
实例:
function check(array) {
const result = array.reduce((obj, entry) => {
if (obj.x === null) {
obj.x = entry.x;
} else if (obj.x !== entry.x) {
obj.x = undefined;
}
obj.y += entry.y;
return obj;
}, {x: null, y: 0});
console.log(result);
}
check([
{a:'titi', x: true, y: 3},
{a:'toto', x: false, y: 6}
]);
console.log("---");
check([
{a:'titi', x: true, y: 3},
{a:'toto', x: true, y: 6}
]);
console.log("---");
check([
{a:'titi', x: false, y: 3},
{a:'toto', x: false, y: 6}
]);
console.log("---");
但是,如果您想要一个 reduce
解决方案并且您不介意创建一堆临时的一次性对象,请查看
我使用 reduce
想出了这个解决方案。似乎有点 hacky,但它应该完成这项工作。在减少数组时,它确定每个 x 值是否相等,然后相应地设置减少对象的 x 值。
let reduced = arr.reduce((acc, curr) => {
acc.x &= acc.x_init === curr.x;
acc.y += curr.y;
}, {x_init: arr[0].x, x: true, y: 0});
reduced.x = reduced.x ? reduced.x_init : undefined;
delete reduced.x_init;
这对于 reduce 来说非常简单:
.reduce((a, b) => ({
x: a.x == b.x ? a.x : undefined,
y: a.y + b.y
}))
实例:
var input = [
{a:'titi', x: true, y: 3},
{a:'toto', x: false, y: 6}
];
console.log(input.reduce((a, b) => ({
x: a.x == b.x ? a.x : undefined,
y: a.y + b.y
})));
感谢@Adassko,我的变体有点长:
[
{a:'titi', x: false, y: 3},
{a:'toto', x: false, y: 6}
]
.reduce((a, b, i) => ({
x : a.x === b.x || i == 0 ? b.x : undefined,
y : a.y + b.y
}))