2

I'am doing some JavaScript exercises and I stumbled upon this one "Write a JavaScript program to filter out the non-unique values in an array."

I tried and found a solution, which worked but it was to cumbersome. A better answer, according to the site, is the following:

const filter_Non_Unique = arr =>
  arr.filter(l => arr.indexOf(l) === arr.lastIndexOf(l));

console.log(filter_Non_Unique([1,2,3,4,4,5,6,6])) // 1,2,3,5

Now I recked my head trying to understand why this solution works but I still don't get it. Can somebody explain to me? Thanks in advance.

Kobe
  • 6,226
  • 1
  • 14
  • 35
Ahmed
  • 41
  • 4

2 Answers2

6

If the element only occurs once in the array, the first index will be the same as the last index, the index will not change for both calls.

eg:

const arr = [1,2,3,4,4,5,6,6]

console.log(arr.indexOf(5))
console.log(arr.lastIndexOf(5))

Since both of of these functions return the same index, filter will keep the element in.

On the other hand if there are multiple values, those values will have different indexes, so the filter will return false, and remove it from the array:

const arr = [1,2,3,4,4,5,6,6]

console.log(arr.indexOf(4))
console.log(arr.lastIndexOf(4))

I've answered a question similar to the one you solved here, you could try that logic too.

Kobe
  • 6,226
  • 1
  • 14
  • 35
2

Beside of the indexOf/lastIndexOf approach which needs a lot of iterating the array, you could take a two loop approach.

By getting an array of single items by using a hash table and three states, like

  • undefined, the standard value of not declared properties of an object,
  • true for the first found value,
  • false for all values who are repeated in the array.

Then filter by the value of the hash table.

const
    filterNonUnique = array => {
        var hash = {};
        for (let v of array) hash[v] = hash[v] === undefined;
        return array.filter(v => hash[v]);
    }

console.log(filterNonUnique([1, 2, 3, 4, 4, 5, 6, 6, 7, 7, 7, 7]))
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • @NinaScholz couldn't it be done in a single `reduce` iteration instead? – briosheje Dec 05 '19 at 10:37
  • Oh, right, didn't think about that. that's probably the most efficient way indeed, otherwise you would need to alter the hash and spread keys to an array, but that would imply filtering, so... – briosheje Dec 05 '19 at 10:45