2

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 }
2
  • 1
    actual result of execution of your code is [4, 4] but not a {3, 5} Commented Jun 14, 2021 at 10:40
  • @Yana Trifonova my bad, I'll edit it Commented Jun 14, 2021 at 10:54

3 Answers 3

4

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);

Sign up to request clarification or add additional context in comments.

2 Comments

It works, thank you! I used entries before, but I'm do it wrong so it return "filter is not a function" error.
@man99 One more efficient solution added. Check it out...
2

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);

Comments

1

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]}}));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.