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))

9
  • 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? Commented Jun 17, 2019 at 22:17
  • Possible duplicate of Finding matches between multiple JavaScript Arrays Commented Jun 17, 2019 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). Commented Jun 17, 2019 at 22:20
  • I posted my attempt... My trouble is with the g Commented Jun 17, 2019 at 22:27
  • The number of arrays will always be changing @cale_b Commented Jun 17, 2019 at 22:28

4 Answers 4

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)

Sign up to request clarification or add additional context in comments.

Comments

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)

Comments

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));

Comments

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]))] )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.