I'm trying to find a way to count the amount of times the direction is 'IN' or 'Out' after grouping them.
for example in the below data I would like Person and Item tag to be the group and then output how many IN's or OUT's show up based on their unique groups.
const data = [
{
Person: 'Jake',
Item_tag: '124',
date: 'Mon May 11 2020',
direction: 'IN',
},
{
Person: 'Jake',
Item_tag: '123',
date: 'Tue May 12 2020',
direction: 'IN',
},
{
Person: 'Jake',
Item_tag: '123',
date: 'Tue May 12 2020',
direction: 'OUT',
},
]
I would expect an output like
Person: Jake Item_tag:123 Incoming: 1 outgoing:1
Person: Jake Item_tag:124 Incoming:1 outgoing:0
Below is what I've tried using reduce, but I couldn't figure out how to get the proper count inside the reduce.
import React from 'react'
type Props = {}
//Data
const data = [
{
Person: 'Jake',
Item_tag: '123',
date: 'Mon May 11 2020',
direction: 'IN',
},
{
Person: 'Mary',
Item_tag: '123',
date: 'Mon May 11 2020',
direction: 'OUT',
},
{
Person: 'Jake',
Item_tag: '123',
date: 'Tue May 12 2020',
direction: 'IN',
},
{
Person: 'Jake',
Item_tag: '123',
date: 'Tue May 12 2020',
direction: 'OUT',
},
]
const result = data.reduce((res, current) => {
// build the grouping (Person Item_tag)
const key = `${current.Person}_${current.Item_tag}`
res[key] = res[key] || {
Person: current.Person,
Item_tag: current.Item_tag,
Count_of_incoming: '0',
Count_of_outgoing: '0',
return res
}, {})
// print values
console.log(Object.values(result))
Any help is appreciated!
CodePudding user response:
You just need one more increment instruction for res[key].Count_of_xxxx
, where xxxx
depends on current.direction
.
A tiny issue: don't inialise these counters as strings, but as numbers.
See the added if..else
:
const data = [
{Person: 'Jake',Item_tag: '123',date: 'Mon May 11 2020',direction: 'IN',},
{Person: 'Mary',Item_tag: '123',date: 'Mon May 11 2020',direction: 'OUT',},
{Person: 'Jake',Item_tag: '123',date: 'Tue May 12 2020',direction: 'IN',},
{Person: 'Jake',Item_tag: '123',date: 'Tue May 12 2020',direction: 'OUT',},
];
const result = data.reduce((res, current) => {
// build the grouping (Person Item_tag)
const key = `${current.Person}_${current.Item_tag}`;
res[key] = res[key] || {
Person: current.Person,
Item_tag: current.Item_tag,
Count_of_incoming: 0,
Count_of_outgoing: 0,
};
if (current.direction === "OUT") {
res[key].Count_of_outgoing ;
} else {
res[key].Count_of_incoming ;
}
return res;
}, {});
// print values
console.log(Object.values(result));
CodePudding user response:
Let's try to group by Person and Item_tag using a separator first. Then using object of objects. Seems appropriate for a more generic solution but for now this works:
const data = [{
Person: 'Jake',
Item_tag: '124',
date: 'Mon May 11 2020',
direction: 'IN',
}, {
Person: 'Jake',
Item_tag: '123',
date: 'Tue May 12 2020',
direction: 'IN',
}, {
Person: 'Jake',
Item_tag: '123',
date: 'Tue May 12 2020',
direction: 'OUT',
},
];
var step1 = data.reduce(function(acc, item) {
var key1 = item.Person;
var key2 = item.Item_tag;
acc[key1] = acc[key1] || {};
acc[key1][key2] = acc[key1][key2] || {IN: 0, OUT: 0}
acc[key1][key2][item.direction] = acc[key1][key2][item.direction] 1
return acc;
}, {})
for (var key1 in step1) {
for (var key2 in step1[key1]) {
console.log(`Person: ${key1} Item_tag:${key2} Incoming: ${step1[key1][key2].IN} outgoing:${step1[key1][key2].OUT}`)
}
}