0

I have an array like this

    arrays = [
        ['a', 'b', 'c', 'd'],
        ['a', 'b', 'c', 'g'],
        ['a', 'b', 'c', 'g', 'x'],
    ]

I need to form one array of all intersection. Like this.

    function get_intersects(arrays) {
        // return all intersections
        return ['a', 'b', 'c', 'g'];
    }

notice how g is returned even though it is not in all three but it is in at least 2 of them.

This is my attempt but the g is missing.

arrays = [
    ['a', 'b', 'c', 'd'],
    ['a', 'b', 'c', 'g'],
    ['a', 'b', 'c', 'g', 'x'],
]

function get_intersects(arrays) {
    return arrays.shift().filter(function (v) {
        return arrays.every((a) => a.indexOf(v) !== -1 );
    });
}



console.log(get_intersects(arrays))
Omar
  • 2,726
  • 2
  • 32
  • 65
  • 2
    Show us the code for what you've tried so far. You're expected to make an effort on your own :) - ALSO - it's unclear - you say "ALL", but then `g` is returned when only in _two_... what's the actual requirement? An intersection in ANY two arrays? And should the solution support an arbitrary number of arrays? – random_user_name Jun 17 '19 at 22:17
  • Possible duplicate of [Finding matches between multiple JavaScript Arrays](https://stackoverflow.com/questions/11076067/finding-matches-between-multiple-javascript-arrays) – random_user_name Jun 17 '19 at 22:19
  • Heh, merge all the arrays, and then find the values that are repeated. Could be an approach (if they do not repeat in the original arrays). – Taplar Jun 17 '19 at 22:20
  • I posted my attempt... My trouble is with the g – Omar Jun 17 '19 at 22:27
  • The number of arrays will always be changing @cale_b – Omar Jun 17 '19 at 22:28
  • Do the inner arrays ever have repeated members? – Mark Jun 17 '19 at 22:31
  • @markMeyer the individual arrays never repeat – Omar Jun 17 '19 at 22:36
  • @Omar -- not the arrays the individual items. Is this possible: `['a', 'b', 'c', 'g', 'x', 'x']` ? – Mark Jun 17 '19 at 22:37
  • good point... in real world they will never repeat like that.. `['a', 'b', 'c', 'g', 'x', 'x']` will never happen – Omar Jun 17 '19 at 22:38

4 Answers4

4

You could also use Set with Array.filter and Array.lastIndexOf:

let data = [ ['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'g'], ['a', 'b', 'c', 'g', 'x'] ]

let result = [...new Set(data.flat().filter((x,i,a) => a.lastIndexOf(x) != i))]

console.log(result)
Akrion
  • 18,117
  • 1
  • 34
  • 54
3

If your goal is to determine if the individual letters are in at least 2 of the arrays, you could just count them. It's not clear if an inner array can have repeats like ['a', 'b', 'c', 'g', 'x', 'x']. Assuming these represent sets and won't have repeated members, it's just a matter of counting and filtering anything with a count greater than one:

var arrays = [
    ['a', 'b', 'c', 'g'],
    ['a', 'b', 'c', 'd'],
    ['a', 'b', 'c', 'g', 'x'],
]

var counts = arrays.reduce((counts, arr) => {
    arr.forEach(c => counts[c] = (counts[c] || 0) + 1)
    return counts
}, {})

let common = Object.keys(counts).filter(k => counts[k] > 1)
console.log(common)

If you can have repeats, you could use a set to make them unique before iterating and counting. Something like:

new Set(arr).forEach(c => counts[c] = (counts[c] || 0) + 1)
Mark
  • 90,562
  • 7
  • 108
  • 148
2

You can use a helper array to put the values you've visited, while you're iterating over your arrays.

const arrays = [
  ['a', 'b', 'c', 'd'],
  ['a', 'b', 'c', 'g'],
  ['a', 'b', 'c', 'g', 'x'],
];

const magic = arrays => {
  const values = [];
  const res = [];
  arrays.forEach(array => {
    array.forEach(e => {
      // if the current value has been visited and is not yet inserted into result array
      if (values.indexOf(e) !== -1 && res.indexOf(e) === -1) res.push(e);
      // if the current value hasn't been visited yet
      if (values.indexOf(e) === -1) values.push(e);
    });
  });
  return res;
};

console.log(magic(arrays));
Ammar
  • 770
  • 4
  • 11
1

Sort to find duplicates, and remove duplicates after :

var arrays = [ ['a', 'b', 'c', 'd'], ['a', 'b', 'c', 'g'], ['a', 'b', 'c', 'g', 'x'] ]

console.log( [...new Set(arrays.flat().sort().filter((v, i, a) => v == a[--i]))] )
Slai
  • 22,144
  • 5
  • 45
  • 53