man99
man99

Reputation: 47

Counting frequency of each element in array - javascript

I'm counting the customer occurrences using reduce like this. Then, I need to display the customer who appear more than 3 times. It works actually, but only display the count because I'm using map.values(). I want it to display the customer name too. Anyone know how to do it? thank you!

const customer = ["Andy", "Drew", "Andy", "Brian", "Andy", "Brian", "Andy", "Brian", "Brian", "Drew", "Brian"];
const custFreq = customer.reduce((acc, curr) => acc.set(curr, (acc.get(curr) || 0) + 1), new Map());
const result = [...custFreq.values()].filter((curr) => curr >= 3.0);
console.log(result); 

result => { 4, 5 }
expected result => { Andy: 4, Brian: 5 }

Upvotes: 2

Views: 2065

Answers (3)

Lajos Arpad
Lajos Arpad

Reputation: 76444

You can combine Object.keys with .filter to achieve that:

    //Combination of keys and filter
    const customer = ["Andy", "Drew", "Andy", "Brian", "Andy", "Brian", "Andy", "Brian", "Brian", "Drew", "Brian"];
    let custFreq = {};
    customer.forEach(item => {
        if (!custFreq[item]) custFreq[item] = 0;
        return custFreq[item]++;
    });
    console.log((Object.keys(custFreq).filter(item => (custFreq[item] > 3))).map(item => {return {[item]: custFreq[item]}}));

Upvotes: 1

Jamiec
Jamiec

Reputation: 136094

You could always use entries instead of values and Object.fromEntries to convert back to an object.

const customer = ["Andy", "Drew", "Andy", "Brian", "Andy", "Brian", "Andy", "Brian", "Brian", "Drew", "Brian"];
const custFreq = customer.reduce((acc, curr) => acc.set(curr, (acc.get(curr) || 0) + 1), new Map());
const result = Object.fromEntries([...custFreq.entries()].filter(([_,count]) => count >= 3.0));
console.log(result);

Upvotes: 2

DecPK
DecPK

Reputation: 25408

You can use Object.entries and reduce to get the name and count whose count is greater than 3.0

Since there is a typo on 7 element i.e. "Brian,". That's why it is giving out count of Brian as 4 instead of 5

const customer = [
  "Andy",
  "Drew",
  "Andy",
  "Brian",
  "Andy",
  "Brian",
  "Andy",
  "Brian,",
  "Brian",
  "Drew",
  "Brian",
];
const custFreq = customer.reduce(
  (acc, curr) => acc.set(curr, (acc.get(curr) || 0) + 1),
  new Map()
);
const result = [...custFreq.entries()].reduce((acc, [key, value]) => {
  if (value >= 3.0) acc[key] = value;
  return acc;
}, {});
console.log(result);

EFFICIENT SOLUTION: Only need to iterate customer array only once

const customer = [
  "Andy",
  "Drew",
  "Andy",
  "Brian",
  "Andy",
  "Brian",
  "Andy",
  "Brian,",
  "Brian",
  "Drew",
  "Brian",
];

const result = {};

const custFreq = customer.reduce((acc, curr) => {
  acc[curr] = (acc[curr] ?? 0) + 1;
  if (acc[curr] >= 3) {
    result[curr] = acc[curr];
  }
  return acc;
}, {});

console.log(custFreq);
console.log(result);

Upvotes: 4

Related Questions