Audi AE
Audi AE

Reputation: 3

Counting occurrence of each value in an array

I have an array of objects containing id and name.

var array = [ {'id':1, 'name': Bob}, {'id':1, 'name': Bob}, {'id':1, 'name': Bob}, {'id':2, 'name': Jeff}, {'id':1, 'name': Bob}, {'id':2, 'name': Jeff}, ]

Using

var result = array.reduce((ac, p) => ({
      ...ac, [p.product_name]: (ac[p.product_name] || 0) + 1
    }),{})

I would get

{Bob: 4, Jeff: 2}

What can I do so that the function returns

 [{name: "Bob", frequency: 4}, {name: "Jeff", frequency: 2}]

Upvotes: 0

Views: 43

Answers (2)

Rickard Elimää
Rickard Elimää

Reputation: 7591

Loop through the array, store the specific property in an object, add new object or increase the number in the array.

It seems that you want to write short code, but I took the liberty of making the function a little bit more dynamic.

var result = function(arr, firstProperty, secondProperty) {
  var reducedArr = [];
  var tempObj = {};
  var currentArrIndex = 0;
  var firstPropertyValue = '';

  secondProperty = secondProperty || 'frequency';

  for (var i = 0; i < arr.length; i++) {
    firstPropertyValue = arr[i][firstProperty];

    if (firstPropertyValue) {
      if (tempObj.hasOwnProperty(firstPropertyValue)) {
        currentArrIndex = tempObj[firstPropertyValue];
        reducedArr[currentArrIndex][secondProperty] += 1;
      } else {
        currentArrIndex = reducedArr.length
        tempObj[firstPropertyValue] = currentArrIndex;

        reducedArr[currentArrIndex] = {};
        reducedArr[currentArrIndex][firstProperty] = arr[i][firstProperty];
        reducedArr[currentArrIndex][secondProperty] = 1;
      }
    }
  }

  return reducedArr;
}

// EXAMPLES
// result(arrays, 'name')
// result(arrays, 'id')
// result(arrays, 'id, 'occurrancies')

Upvotes: 0

brk
brk

Reputation: 50291

Use findIndex along with reduce

findIndex will get the index of the object in the array where the name matches. If it is not -1 , there there does not exist any object whose name value matches with the array. If it exist then update the value of the frequency key

var arrays = [{
  'id': 1,
  'name': 'Bob'
}, {
  'id': 1,
  'name': 'Bob'
}, {
  'id': 1,
  'name': 'Bob'
}, {
  'id': 2,
  'name': 'Jeff'
}, {
  'id': 1,
  'name': 'Bob'
}, {
  'id': 2,
  'name': 'Jeff'
}]

let newArray = arrays.reduce(function(acc, curr, index) {
  let getIndex = acc.findIndex(function(item) {
    return item.name === curr.name;
  })
  if (getIndex === -1) {
    acc.push({
      name: curr.name,
      frequency: 1
    })
  } else {
    acc[getIndex].frequency = acc[getIndex].frequency + 1

  }
  return acc;
}, [])

console.log(newArray)

Upvotes: 1

Related Questions