Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map/Set to maintain unique array of arrays, Javascript

I am trying to build unique array of arrays such that whenever I have new array to add it should only add if it doesn't already exist in collection

E.g. store all unique permutations of [1,1,2]

Actual : [[1,1,2],[1,2,1],[1,1,2],[1,2,1],[2,1,1],[2,1,1]]
Expected : [[1,1,2],[1,2,1],[2,1,1]]

Approaches I tried:

  1. Array.Filter: Doesn't work because arrays are object and each value in uniqueArrComparer is a unique object reference to that array element.
function uniqueArrComparer(value, index, self) {
  return self.indexOf(value) === index;
}

result.filter(uniqueArrComparer)
  1. Set/Map: Thought I can build a unique array set but it doesn't work because Set internally uses strict equality comparer (===), which will consider each array in this case as unique.
    We cannot customize object equality for JavaScript Set

  2. Store each array element as a string in a Set/Map/Array and build an array of unique strings. In the end build array of array using array of unique string. This approach will work but doesn't look like efficient solution.

Working solution using Set

let result = new Set();

// Store [1,1,2] as "1,1,2"
result.add(permutation.toString());

return Array.from(result)
  .map(function(permutationStr) {

    return permutationStr
      .split(",")
      .map(function(value) {

        return parseInt(value, 10);
      });
  });

This problem is more of a learning exercise than any application problem.

like image 318
Rohit Avatar asked May 04 '17 01:05

Rohit


1 Answers

One way would be to convert the arrays to JSON strings, then use a Set to get unique values, and convert back again

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

let set  = new Set(arr.map(JSON.stringify));
let arr2 = Array.from(set).map(JSON.parse);

console.log(arr2)
like image 81
adeneo Avatar answered Nov 16 '22 02:11

adeneo