2

I have an array of strings:

var array = ['bob', 'charlie', 'bob', 'bob']; 

that I want to remove duplicates from, and then I'd like to convert it to an array of objects whilst adding a duplicate count property.

This is what I want to achieve:

var filteredData = [{ name: 'bob', count: 3}, { name: 'charlie', count: 1}];

How can I do that?

Floern
  • 33,559
  • 24
  • 104
  • 119
  • Possible duplicate of [How to count Matching values in Array of Javascript](https://stackoverflow.com/questions/2228362/how-to-count-matching-values-in-array-of-javascript) – Patrick Barr Jul 06 '17 at 21:30
  • not an exact duplicate, but answer will be a slightly modified version of the answer – Patrick Barr Jul 06 '17 at 21:30

3 Answers3

3

Ecmascript5 solution using Array.prototype.reduce() function:

var arr = ['bob', 'charlie', 'bob', 'bob'],
    counts = arr.reduce(function(r,s){
        (!r[s])? r[s] = {name: s, count: 1} : r[s]['count']+=1;
        return r;
    }, {}),
    result = Object.keys(counts).map(function(k){ return counts[k]; });
    
console.log(result);

Ecmascript6 version (with Object.values() function):

var arr = ['bob', 'charlie', 'bob', 'bob'],
    result = Object.values(arr.reduce((r,s) => {
        (!r[s])? r[s] = {name: s, count: 1} : r[s]['count']+=1;
        return r;
    }, {}));
    
console.log(result);
RomanPerekhrest
  • 88,541
  • 4
  • 65
  • 105
0

Using Map with Array#reduce:

const array = ['bob', 'charlie', 'bob', 'bob']; 

const result = [...array.reduce((map, name) => {
  const current = map.get(name) || { name, count: 0 };
  
  current.count++;

  return map.set(name, current);
}, new Map()).values()];

console.log(result);
Ori Drori
  • 183,571
  • 29
  • 224
  • 209
0

Here is some straightforward usage of Array.prototype.reduce:

const data = ['bob', 'charlie', 'bob', 'bob']

const result = data.reduce(function(prev, curr) {
  const index = prev.findIndex(el => el.name === curr)

  if (index !== -1) {
    prev[index].count += 1
  } else {
    prev.push({ name: curr, count: 1 })
  }

  return prev
}, [])

console.log(result)
dfsq
  • 191,768
  • 25
  • 236
  • 258