Reputation: 3296
I'm trying to get the count of matching data from two arrays (of objects). I want to find all instances of active
being true
for each group, and then create a new array that lists the count of matching items from the things array.
const groups = [
{id: 234},
{id: 423},
{id: 474},
{id: 864}
];
const things = [
{id: 1, active: false, group: 234},
{id: 2, active: true, group: 234},
{id: 3, active: false, group: 234},
{id: 4, active: true, group: 423},
{id: 5, active: true, group: 423},
{id: 6, active: false, group: 423}
];
The result I want to get is the group ID and the count of things that are active from the things
array. I can use filter to return the active items, but how to get the count and get a new array like the output below?
I want the final results to look like :
[
{group: 234, active: 1},
{group: 423, active: 2}
];
Upvotes: 0
Views: 667
Reputation: 17190
One possible solution is to use Array.reduce() to generate an object
with the active
count of the desired groups. Then, on a second step, you can use Array.map() to obtain the desired output.
const groups = [{id: 234}, {id: 423}, {id: 474}, {id: 864}];
const things = [
{id: 1, active: false, group: 234},
{id: 2, active: true, group: 234},
{id: 3, active: false, group: 234},
{id: 4, active: true, group: 423},
{id: 5, active: true, group: 423},
{id: 6, active: false, group: 423}
];
let groupsSet = new Set(groups.map(g => g.id));
let res = things.reduce((acc, {group, active}) =>
{
if (active && groupsSet.has(group))
acc[group] = (acc[group] || 0) + 1;
return acc;
}, {});
res = Object.entries(res).map(([group, active]) => ({group, active}));
console.log(res);
.as-console {background-color:black !important; color:lime;}
.as-console-wrapper {max-height:100% !important; top:0;}
Upvotes: 1
Reputation: 386610
You could filter, filter and count the items.
const
groups = [{ id: 234 }, { id: 423 }, { id: 474 }, { id: 864 }]
things = [{ id: 1, active: false, group: 234 }, { id: 2, active: true, group: 234 }, { id: 3, active: false, group: 234 }, { id: 4, active: true, group: 423 }, { id: 5, active: true, group: 423 }, { id: 6, active: false, group: 423 }],
groupsSet = new Set(groups.map(({ id }) => id)),
result = Array.from(
things
.filter(({ active }) => active)
.filter(({ group }) => groupsSet.has(group))
.reduce((m, { group }) => m.set(group, (m.get(group) || 0) + 1), new Map),
([group, active]) => ({ group, active })
);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 1
Reputation: 118271
You can do it as below, first filter and then group them by active value.
const groups = [{
id: 234
}, {
id: 423
}, {
id: 474
}, {
id: 864
}]
const things = [{
id: 1,
active: false,
group: 234
}, {
id: 2,
active: true,
group: 234
}, {
id: 3,
active: false,
group: 234
}, {
id: 4,
active: true,
group: 423
}, {
id: 5,
active: true,
group: 423
}, {
id: 6,
active: false,
group: 423
}];
const temp = things.filter(thing => {
return groups.find(group => group.id == thing.group && thing.active)
}).reduce((mem, cur) => {
mem[cur.group] = (mem[cur.group] || 0) + 1;
return mem;
}, {});
const result = Object.keys(temp).map(key => ({
'group': key,
active: temp[key]
}));
console.log(result);
Upvotes: 1