Home > Back-end >  How to count object property occurrence in an array by adding count property to the object propertie
How to count object property occurrence in an array by adding count property to the object propertie

Time:03-03

Am not sure what am missing or doing wrong, but I actually want to get a new array containing the properties from one of the objects in the original array and add a property called 'count' to the object that will keep count of the occurrence of a property in the object (example: that property could be title or county, but for my case it's county) and return a new array of objects.

having the array below:

let reports = [
  {
    county: 'Montserrado',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Extortion',
    city: 'paynesville'
  },
  {
    county: 'Lofa',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Bribery',
    city: 'voinjama'

  },
  {
    county: 'Montserrado',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Bribery',
    city: 'brewerville'
  },
  {
    county: 'Lofa',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Crynism',
    city: 'kolahuun'
  },
  {
    county: 'Grand Bassa',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Molestation',
    city: 'buchanan'
  },
  {
    county: 'Montserrado',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Bribery',
    city: 'paynesville'
  },
];

I want to reduce it to an array like this dynamically:

[
  {
    county: 'Lofa',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Crynism',
    city: 'kolahuun',
    count: 2
  },
  {
    county: 'Grand Bassa',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Molestation',
    city: 'buchanan',
    count: 1
  },
  {
    county: 'Montserrado',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Bribery',
    city: 'paynesville',
    count: 3
  },
];

I tried achieving the above with the code block below:

const countyCount = reports
  .map(dataItem => dataItem.county) // get all media types
  .filter((county, index, array) => array.indexOf(county) === index); // filter out duplicates

const counts = countyCount
  .map(countyCount => ({
    county: countyCount,
    count: reports.filter(item => item.county === countyCount).length
  }));

but am getting the below result, which is not what I want

[
  {county: 'Montserrado', count: 3},
  {county: 'Grand Bassa', count: 1},
  {county: 'Lofa', count 2}
]

CodePudding user response:

You were very close to achieve it with your code, just needed to add an index to your map method, so that you can extract the wanted properties from the array, like so:

const countyCount = reports
      .map(dataItem => dataItem.county) 
      .filter((county, index, array) => array.indexOf(county) === index)

    const counts = countyCount
      .map((countyCount,i) => ({
        county: countyCount,
        lat: reports[i].lat,
        lng: reports[i].lng,
        title: reports[i].title,
        count: reports.filter(item => item.county === countyCount).length
      }))

Try the following snippet

let reports = [
  {
    county: 'Montserrado',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Extortion',
    city: 'paynesville'
  },
  {
    county: 'Lofa',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Bribery',
    city: 'voinjama'

  },
  {
    county: 'Montserrado',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Bribery',
    city: 'brewerville'
  },
  {
    county: 'Lofa',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Crynism',
    city: 'kolahuun'
  },
  {
    county: 'Grand Bassa',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Molestation',
    city: 'buchanan'
  },
  {
    county: 'Montserrado',
    lat: '1.454354',
    lng: '-4.454254',
    title: 'Bribery',
    city: 'paynesville'
  },
];

const countyCount = reports
  .map(dataItem => dataItem.county) // get all media types
  .filter((county, index, array) => array.indexOf(county) === index); // filter out duplicates

const counts = countyCount
  .map((countyCount,i) => ({
    county: countyCount,
    lat: reports[i].lat,
    lng: reports[i].lng,
    title: reports[i].title,
    count: reports.filter(item => item.county === countyCount).length
  }));
  
console.log(counts)  

CodePudding user response:

Its because the countyCounty array isn't an array of objects, it's an array of strings (county names), so you can't access any of the other data when you use .map.

You could use this beast of a reduce function to get your desired outcome. Essentially you are iterating over the reports array and produce a new array. For each index in the old array, you check if an object already exists in the new array with the same county name. If not, you add it to the new list with an additional count attribute, otherwise you pass and move to the next index:

const counts= reports.reduce(
  (prev, curr) => prev.some(
    (item) => item.county === curr.county)  //does the county already exist ?
      ? prev // if yes dont add to the new array
      : prev.concat({ // if no add to the new array
          ...curr, 
          count: reports.filter((item) => item.county === curr.county).length
      }), 
  [])
  • Related