Home > Software engineering >  obtaining a count after using reduce in Javascript
obtaining a count after using reduce in Javascript

Time:07-23

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}`)
  }
}

  • Related