Although you can shoehorn this into a reduce call (because any array operation can be shoehorned into a reduce), there's no benefit to doing so. Just use a loop:
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;
}
Live Example:
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("---");
But again, you can shoehorn that into a reduce if you want by always returning the same object:
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});
Live Example:
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("---");
But, if you want a reduce solution and you don't mind creating a bunch of temporary throw-away objects, check out Adassko's answer. Simple and straight-forward, and 99.9% of the time, you don't care about the temporary object creation.