Iris Hadar
Iris Hadar

Reputation: 21

Javascript find all duplicate items from multiple arrays

I have array of arrays, each array has unique items . I need to find and collect all duplicate items between all arrays to new array .

For this input : [[1,2,6,9],[3,2,7,5,12],[1,3]]

I need this output: [1,2,3]

Does anyone now what is the best way to do it ?

Upvotes: 0

Views: 1959

Answers (3)

Carsten Massmann
Carsten Massmann

Reputation: 28196

Depending on what is meant by "duplicates" @Nina's solution can be modified to include only those cases where the value occurrs exactly twice. My slightly modified example snippet will exclude the value 1 as it occurs three times:

const data = [[1, 2, 6, 9], [3, 2, 7, 5, 12], [1, 3], [1, 7]], k=2, // no. of occurrences

result = data.reduce((o,c,i)=>(c.forEach(v=>o[v]=(o[v]||0)+1),o),[])
             .map((v,i,a)=>(a[i] = v===k ? i : undefined ))
             .filter(v=>v);

console.log(result);

caveat: This will only work with numeric values (integers!).

But here is another version that will work with any kind of content:

var data = [[1, 2, 6, 9, "c"], [3, "a", 2, 7, 5, 12], [1, "c", 3], [1, 7]], k=2;

res=[...data.reduce((o,c,i)=>(c.forEach(v=>o.set(v,(o.get(v)||0)+1)),o),
                    new Map()).entries()]
    .filter(([k,v])=>v===2)
    .map(([k,v])=>k)
   

console.log(res)

Update

If you want the addresses of the first location the duplicates were found you could do it like this:

var data = [[1, 2, 6, 9, "c"], [3, "a", 2, 7, 5, 12], [1, "c", 3], [1, 7]], n=2;

res=[...data.reduce((o,c,i)=>(c.forEach(v=>o.set(v,(o.get(v)||0)+1)),o),
                    new Map()).entries()]
    .filter(([k,v])=>v===n)
    .map(([k,v],j)=>[data.findIndex((d,i)=>(j=d.indexOf(k))>-1)+"_"+j, k])

console.log(Object.fromEntries(res))

Upvotes: 0

Shubham Dixit
Shubham Dixit

Reputation: 1

You can try this, optimal with O(3N)=== O(N) complexity

let arr = [
  [1, 2, 6, 9],
  [3, 2, 7, 5, 12],
  [1, 3]
];

let a = arr.flat()

let obj = {};

for (let i = 0; i < a.length; i++) {
  if (obj[a[i]]) obj[a[i]]++;
  else obj[a[i]] = 1
}
let repeated = [];
for (let i in obj) {
  if (obj[i] > 1) {

    repeated.push(i)
  }
}

console.log(repeated)

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386578

You could take a closure over an object for a count of the values.

const
    data = [[1, 2, 6, 9], [3, 2, 7, 5, 12], [1, 3]],
    result = data
        .flat()
        .filter(
            (o => v => (o[v] = (o[v] || 0) + 1) === 2)
            ({})
        );

console.log(result);

Upvotes: 1

Related Questions