Skip to content

Instantly share code, notes, and snippets.

@OleksiyRudenko
Last active November 3, 2020 11:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OleksiyRudenko/01f161d045b1c347ac2d72a2e47d9c11 to your computer and use it in GitHub Desktop.
Save OleksiyRudenko/01f161d045b1c347ac2d72a2e47d9c11 to your computer and use it in GitHub Desktop.
Counting entries in an array

Classics:

Count number of each entry in an array. I.e. someFunc(['a', 'b', 5, 'a', 2, 5]) should result in

{
  2: 1,
  5: 2,
  'a': 2,
  'b': 1
}

So, we've got const arr = ['a', 'b', 5, 'a', 2, 5] as input.

Approach 1 - Simple reduce

arr.reduce((acc,e) => { acc[e] = 1 + acc[e] || 1; return acc}, {})`
// { '2': 1, '5': 2, 'a': 2, 'b': 1 }

Approach 1.1 - Advanced simple reduce

Effect of comma operator: last expression is returned as a result.

arr.reduce((acc,e) => ( acc[e] = 1 + acc[e] || 1, acc), {})
// { '2': 1, '5': 2, 'a': 2, 'b': 1 }

Approach 2 - Employ Map

Notice that numeric entries remain numeric.

arr.reduce((acc, e) => acc.set(e, 1 + (acc.get(e) || 0)), new Map());
// Map { 'a' => 2, 'b' => 1, 5 => 2, 2 => 1 }

Approach 3 - forEach (for of?)

Better in performance vs side effects.

let counts = {};
arr.forEach(e => {
    counts[e] = 1 + counts[e] || 1;
  });
counts
// { '2': 1, '5': 2, 'a': 2, 'b': 1 }
@OleksiyRudenko
Copy link
Author

Easter egg: transpose matrix

var arr = [
  [1, 2],
  [1, 2, 3],
  [1, 2, 3, 4]
];

/*
 * arr[0].length = 4 = number of result rows
 * arr.length = 3 = number of result cols
 */

var result = Array.from({ length: arr.reduce(function(max, item) { return item.length > max ? item.length : max; }, 0) }, function(x, row) {
  return Array.from({ length: arr.length }, function(x, col) {
    return arr[col][row];
  });
});

console.log(result);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment