# values - javascript push unique object to array

## How to get distinct values from an array of arrays in JavaScript using the filter() method? (5)

### Effective solution:

`O(n)` operations, where `n` is the length of `x` array

`O(n)` memory space, where `n` is the length of `x` array

``````const x = [[1, 2], [3, 4], [1, 2]];

const arrayTable = Object.create(null);

const uniqueArrays = x.filter(arr => {
const arrStr = JSON.stringify(arr);

if (!arrayTable[arrStr]) {
arrayTable[arrStr] = true;
return true;
}

return false;
});

console.log(uniqueArrays);``````

I have an array like this:

``let x = [[1, 2], [3, 4], [1, 2], [2, 1]];``

What should I do to retrieve an array without the duplicates?

``[[1, 2], [3, 4], [2, 1]];``

I would like to use the filter method. I tried this but it doesn't work:

``x.filter((value,index,self) => (self.indexOf(value) === index))``

EDIT: as I specified to use the filter method, I don't think this question is a duplicate. Also, I got several interesting answers.

Filter just causes things to get into O(n^2).

The currently accepted answer uses `.filter((itm, idx, arr) => arr.indexOf(itm) === idx)` which will cause the array to be iterated each time during each iteration... n^2.

Why even go there? Not only that, you need to parse in the end. It is a lot of excess.

There is no real good way to filter without hitting O(n^2) here.

Instead, just use reduce. It is very straightforward and fast easily accomplishing O(n).

"Bin reduce the set to unique values."

``````let x = [[1, 2], [3, 4], [1, 2], [2, 1]];
let y = Object.values(x.reduce((p,c) => (p[JSON.stringify(c)] = c,p),{}));
console.log(y);``````

If you were to have to go the route of filter, then n^2 must be used. You can iterate each item looking for existence using every.

"Keep every element which does not have a previous duplicate."

``````let x = [
[1, 2],
[3, 4],
[1, 2],
[2, 1]
];
let y = x.filter((lx, li) =>
x.every((rx, ri) =>
rx == lx ||
(JSON.stringify(lx) != JSON.stringify(rx) || li < ri))
);
console.log(y);``````

The equivalent to

``x.filter((value,index,self) => (self.indexOf(value) === index))``

would be

``````x.filter((v,i,self) => {
for1:
for (let j = 0; j < self.length; j++) {
if (i == j) {
return true;
}
if (self[j].length != v.length) {
continue;
}
for (let k = 0; k < v.length; k++) {
if (self[j][k] != v[k]) {
continue for1;
}
}
return false;
}
return true;
})``````

Unlike some of the other answers, this does not require a conversion to string and can thus work with more complex values. Use `===` instead of `==` if you want.

The time complexity is not great, of course.

This is a solution with time complexity of O(n) where n is the number of elements in your array.

Using the filter method as the OP wants it:

``````    const x = [[1, 2], [3, 4], [1, 2], [2, 1]];
const s = new Set();

const res = x.filter(el => {
if(!s.has(el.join(""))) {
return true;
}
return false
})

console.log(res)``````

My personal preference here is to use ForEach as it looks more readable.

``````const x = [[1, 2], [3, 4], [1, 2], [2, 1]];
const s = new Set();
const res = [];

x.forEach(el => {
if(!s.has(el.join(""))) {
res.push(el)
}
})

console.log(res);``````

We are using a Set and a simple combination of the elements of the array to make sure they are unique. Otherwise this would become O(n^2).

`indexOf` does not work on identical instances of `arrays` / `objects` type elements within an array, as such arrays just hold references.

In filter function instance you get via parameter `v` (in below code) is not the same instance as stored in array, making `indexOf` unable to return the index of it.

In below code, by converting objects to strings we can use `indexOf` to find duplicates.

``````let x = [[1, 2], [3, 4], [1, 2], [2, 1]];

console.log(x.
map(function(v){
return JSON.stringify(v)
})
.filter(function(v, i, o) {
return o.length == i ? true : o.slice(i + 1).indexOf(v) == -1;
})
.map(function(v) {
return JSON.parse(v)
})
);`````` 