1

I write a function that receives 2 arrays and returns an array that has elements that exist in both arrays. For example, if I pass [6,7,8,9] and [1,8,2,6], it should return [6,8].

My aim is not to use loops here.

I use this code:

const uniqueElements= (arr1, arr2) => {
return arr1.filter(it1=> arr2.filter((it2) => it2===it1).length>0)
}

However, if there are duplicate elements in arrays (e.g. [6,7,8,9,6] and [1,8,2,6,6]), it returns [6, 8, 6].

How should I mend my code so that it would return only unique elements without duplicates? Is it possible without using loops?

sinnerwithguts
  • 573
  • 7
  • 20
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#Implementing_basic_set_operations – melpomene Sep 23 '19 at 06:38
  • Possible duplicate of [Get all unique values in a JavaScript array (remove duplicates)](https://stackoverflow.com/questions/1960473/get-all-unique-values-in-a-javascript-array-remove-duplicates) – Nick Parsons Sep 23 '19 at 06:40
  • 1
    Wrap your result in a `Set` to remove duplicates and then use `Array.from` to get your array back – Nick Parsons Sep 23 '19 at 06:41
  • You can group the result after `array.filter`. You could use library like `linq.js` for grouping. – hiFI Sep 23 '19 at 06:52

4 Answers4

0

For your scenario use this -

constant uniqueElements= (arr1, arr2) => {
return Array.from(new Set(arr1.filter(it1=> arr2.filter((it2) => it2===it1).length>0)))
}

Hope this helps

Vinay sharma
  • 745
  • 5
  • 14
0

Solution using Set from https://2ality.com/2015/01/es6-set-operations.html:

const uniqueElements = (arr1, arr2) => {
    const a = new Set(arr1);
    const b = new Set(arr2);
    const intersection = new Set(
        [...a].filter(x => b.has(x)));
    return Array.from(intersection);
}
Thommath
  • 28
  • 4
0

If you just want to get unique value which appears on both of the array, you just first change both of the array's to Set, loop through one Set and check if it's present on other or not, if it present return true from filter else return false,

const uniqueElements= (arr1, arr2) => {
  let set1 = new Set(arr1)
  let set2 = new Set(arr2)
  return [...set1].filter(it1=> set2.has(it1))
}

console.log(uniqueElements([6,7,8,9],[1,8,2,6]))
console.log(uniqueElements([6,7,8,9,6],[1,8,2,6,6]))

Ref to read about Set Set MDN

Code Maniac
  • 37,143
  • 5
  • 39
  • 60
  • Just keep in mind that [`new Set(iterable)` **is not supported in `Internet Explorer`**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#Browser_compatibility), that's why using `Set` is not always recommended especially when it can be avoided. :) – cнŝdk Sep 23 '19 at 12:25
  • @cнŝdk can be easily transpiled by using [`Babel`](https://babeljs.io/) and if not using babel then can use [`polyfill`](https://www.npmjs.com/package/es6-set) – Code Maniac Sep 23 '19 at 12:42
0

Simply you can just use Array#some() method to write the condition inside your Array#filter() method's callback:

const uniqueElements = (arr1, arr2) => {
  let viewed = [];
  return arr1.filter(it1 => {
    let found = arr2.some((it2) => it2 === it1) && viewed.indexOf(it1) == -1;
    viewed.push(it1);
    return found;
  });
}

Note:

This doesn't take duplicates, with the use of viewed array and viewed.indexOf(it1) == -1 condition.

Demo:

const uniqueElements = (arr1, arr2) => {
  let viewed = [];
  return arr1.filter(it1 => {
    let found = arr2.some((it2) => it2 === it1) && viewed.indexOf(it1) == -1;
    viewed.push(it1);
    return found;
  });
}

let a1 = [6,7,8,9,6];
let a2 = [1,8,2,6,6];

console.log(uniqueElements(a1, a2));
cнŝdk
  • 31,391
  • 7
  • 56
  • 78