Home > Software design >  Filtering and counting values of array of objects Javascript
Filtering and counting values of array of objects Javascript

Time:07-15

I have an array of objects that looks like this:

[{
date: "07-14-2022",
  report: [{
    vehicles: [{
      id: "uid",
      status: "active",
      type: "car"
    },
    {
      id: "uid",
      status: "oos",
      type: "bus"
    },
    {
      id: "uid",
      status: "pm",
      type: "bus"
    }
    ]
  }]
}]

I'm trying to achieve excluding any status other than "oos" or "pm" (was thinking about first using filter here for the first stage). And then I needed to group all the unique values for type so I could provide a breakdown of total numbers for each. So, in the end it would look like:

bus: 2

This is the first stage I was starting to work on, but having trouble...

  getReport() {
    this.backend.getAnalyticsReport().subscribe(
      response => {
        console.log(this.processReport(response))
      }
    )

    
  }

  processReport(obj: any) {
    return obj.filter((element: any) => this.filterStatus(element.vehicles))
  }

  filterStatus(element: any) {

    if (element.status === 'oos' || 'pm') { 
      return true
    } else {
      return false
    }
  }

CodePudding user response:

filter first then use reduce to group. This is a trick I've learned from this answer

var data = [{
    id: "uid",
    status: "active",
    type: "car"
  },
  {
    id: "uid",
    status: "oos",
    type: "bus"
  },
  {
    id: "uid",
    status: "pm",
    type: "bus"
  }
]

var result = data
  .filter(item => ['oos', 'pm'].indexOf(item.status) > -1)
  .reduce(function(agg, item) {
    agg[item.type] = (agg[item.type] || 0)   1
    return agg;
  }, {})
console.log(result)

CodePudding user response:

You could do something like this using the Array.reduce() and Array.includes() methods. I modified the data to add in extra car calues that would be counted and added in an extra date to demonstrate how you could get the counts by day.

const data = [{
    date: "07-14-2022",
    report: [{
      vehicles: [{
          id: "uid",
          status: "active",
          type: "car"
        },
        {
          id: "uid",
          status: "oos",
          type: "bus"
        },
        {
          id: "uid",
          status: "pm",
          type: "bus"
        },
        {
          id: "uid",
          status: "pm",
          type: "car"
        },
        {
          id: "uid",
          status: "active",
          type: "bus"
        }
      ]
    }]
  },
  {
    date: "07-15-2022",
    report: [{
      vehicles: [{
          id: "uid",
          status: "active",
          type: "car"
        },
        {
          id: "uid",
          status: "oos",
          type: "car"
        },
        {
          id: "uid",
          status: "pm",
          type: "bus"
        },
        {
          id: "uid",
          status: "pm",
          type: "bus"
        },
        {
          id: "uid",
          status: "active",
          type: "bus"
        }
      ]
    }]
  }
];

const types = ["oos", "pm"];

const results = data.reduce((a, c) => {
  a[c.date] = c.report[0].vehicles.reduce((a2, c2) => {
    if (types.includes(c2.status)) {
      a2[c2.type] ??= 0;
      a2[c2.type]  ;
    }
    return a2;
  }, {})
  return a
}, {});

document.querySelector('pre').innerText = JSON.stringify(results, null, 3);
<pre></pre>

  • Related