elDrimm
elDrimm

Reputation: 106

JavaScript - Count and remove duplicates from array of objects with es6

I'm trying to fix this, but I'm a little bit stuck and need some help/advise. I'm trying to get to know es6 better and better, but I'm clueless on what's the best way to fix my problem.

I have a large json I'm fetching which looks somewhat like this:

[
    {
        "company": "Google",
        "location": "USA",
        "email": null
    },
    {
        "company": "Microsoft",
        "location": "USA",
        "email": "[email protected]"
    },
    {
        "company": "Google",
        "location": "NLD",
        "email": "[email protected]"
    }
]

I display these in a table and want to add checkbox filters but I also want to add a count next to it, like so:

[x] Google (2)
[ ] Microsoft (1)
// other function call
[ ] [email protected] (2)

I have this function I call every every key (company, location, email):

function filterArr(data, key) {

    data.forEach(element => {

        let countedData = data.filter((el) => {
            return el[key] == element[key]
        }).length;
// console.log(element[key] + ": " + countedData);
    });

    data = data.filter((item, index, self) => self.findIndex( t => t[key] === item[key] && item[key] != null) === index )
// console.log(data)
    return data;
}

filterArr(data, "company");

The output I'm trying to achieve with the above function is: Google: 2 Microsft: 1

The foreach is correctly counting the key values, but obviously logging the following: Google: 2 Microsoft: 1 Google: 2

And the filter console.log shows Google and Microsoft (just once, like I want :)

Now I need to combine these 2, but I'm not sure how to and what's the best way to do so. (see my fiddle: https://jsfiddle.net/z359qo1d/)

Do you know what to do next?

Upvotes: 3

Views: 3711

Answers (2)

Robert Moskal
Robert Moskal

Reputation: 22553

I'd do it a little bit differently:

let _in = [
{
    "company": "Google",
    "location": "USA",
    "email": null
},
{
    "company": "Microsoft",
    "location": "USA",
    "email": "[email protected]"
},
{
    "company": "Google",
    "location": "NLD",
    "email": "[email protected]"
}
]

function countEm(accum, each) {
  if (! accum[each.company] )
    accum[each.company] = 0
  accum[each.company] += 1
  return accum
}

console.log(_in.reduce(countEm, {}))

Upvotes: 1

eltonkamami
eltonkamami

Reputation: 5190

Array.prototype.reduce is a perfect match for what you want

function filterArr(data, key){
  return data.reduce( (result, current) => {
    if(!result[current[key]]){
      result[current[key]] = 1;
    } else {
      result[current[key]] += 1;
    }
    return result;    
  }, {})
}

The above will return an object like this

{
  Google: 2,
  Microsoft: 1
}

Upvotes: 7

Related Questions