How to count element appearing times

How to count element appearing times?

for example, If I have:

let arr = [2, 3, ,1, 3, 3, 1, 3]

The result is:

let obj = {
  1: 2,
  2: 1,
  3: 4
}

So 1 is appearing two times and number 3 is appearing four times.

A simple loop can do that:

const arr = [2, 3, 1, 3, 3, 1, 3];
let obj = {};
arr.forEach(function (num) {
  const count = obj[num] || 0;
  obj[num] = count + 1;
});

Instead of using count, you can update the obj property first to default to 0, then just increment that.

const arr = [2, 3, 1, 3, 3, 1, 3];
let obj = {};
arr.forEach(function (num) {
  obj[num] = obj[num] || 0;
  obj[num] += 1;
});

Using let though is a signal, warning us that there tends to be better ways to do things.

In this case let is used because we are changing the object. Instead of reaching out to change something (which is typically bad), we can use reduce instead to update an object and return the completed thing.

const arr = [2, 3, 1, 3, 3, 1, 3];
let obj = {};
obj = arr.reduce(function (obj, num) {
  obj[num] = obj[num] || 0;
  obj[num] += 1;
  return obj;
}, {});

That way we can assign that reduced object letting us replace let with const, and are left with better code in the process.

const arr = [2, 3, 1, 3, 3, 1, 3];
const obj = arr.reduce(function (obj, num) {
  obj[num] = obj[num] || 0;
  obj[num] += 1;
  return obj;
}, {});

Can we improve the inside of the function any further?

We could combine both lines that update obj[num]

const arr = [2, 3, 1, 3, 3, 1, 3];
const obj = arr.reduce(function (obj, num) {
  obj[num] = (obj[num] || 0) + 1;
  return obj;
}, {});

Or we could increase the property and only assign a default of 1 for when it starts with no value:

const arr = [2, 3, 1, 3, 3, 1, 3];
const obj = arr.reduce(function (obj, num) {
  obj[num] = (obj[num] + 1) || 1;
  return obj;
}, {});

But I think that I prefer the previous set of code with = (obj[num] || 0) + 1

1 Like

I saw that you use forEach in some examples.

What are the differences between forEach and map?

The forEach method just loops over the items in the array, running the function on each item of the array. If you want anything done based on then you typically need to reach out from that function to change something else in the code. That is considered to be inappropriate behaviour.

The map method does the same as the forEach method, except that the returned values from the function are collected together as a new array. That way you don’t need to reach out from the function to change things, and end up with a new array that’s based in some way on the array that you started with.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.