Reputation: 6501
I'm wondering if it's possible to achieve the below in a cleaner/more efficient way?
const data = [
{ active: false },
{ active: false },
{ active: true },
{ active: false },
{ active: true },
]
const split = (data) => {
const activeData = data.filter(({active}) => active).map(element => 1)
const inactiveData = data.filter(({active}) => !active).map(element => 0)
return [
activeData,
inactiveData,
]
}
console.log(split(data))
The problem here, I think, is that this approach is not efficient, because it's filtering and mapping through the same array twice. Is there a way to do it just once?
Upvotes: 0
Views: 707
Reputation: 36341
You pretty much have a clean way to do it, however using multiple array functions requires more loops over the data.
Reduce will allow us to do this just once.
const data = [
{ active: false },
{ active: false },
{ active: true },
{ active: false },
{ active: true },
]
const split = (data) =>
data.reduce((acc, {active}) => acc[+!active].push(+active) && acc, [[],[]])
console.log(split(data))
Upvotes: 0
Reputation: 413826
Unless your array is immense, it's not going to make any difference. However you could indeed do this in one pass through the array:
const split = (data) =>
data.reduce((rv, entry) =>
(rv[+!entry.active].push(+entry.active), rv)
, [[], []]);
console.log(split([{active: true}, {active: false}, {active: false}]))
The +
operators convert the boolean values to numbers (0 or 1). The "rv" parameter to the .reduce()
callback is the "return value", or the accumulator into which the .reduce()
callback builds up the result. In this code, the callback uses the "active" flag (negated) to pick either the first array (index 0) or the second array (index 1) in the accumulator "array of arrays". The value pushed into the chosen array is then either 0 or 1, again obtained from the "active" value by converting it to a number.
Upvotes: 1
Reputation: 386680
You could take a single loop and reduce the array using an object as target.
const
data = [{ active: false }, { active: false }, { active: true }, { active: false }, { active: true }],
{ true: activeData, false: inactiveData } = data.reduce((r, { active }) =>
(r[active].push(+active), r),
{ true: [], false: [] }
);
console.log(activeData);
console.log(inactiveData);
Upvotes: 0