DEV Community

Cover image for How to Get the Intersection of Two Arrays
Jake Z.
Jake Z.

Posted on • Edited on • Originally published at algodaily.com

How to Get the Intersection of Two Arrays

Oftentimes, interviewers will test you on things that are deceptively easy. We saw this in Reverse a String, and will see more in future challenges. But sometimes you might get tested on a concept that, while a bit trivial, is really useful in day to day software engineering.

One of those things is array manipulation, or basically doing things to an array that creates some kind of transformation.

Prompt

Can you write a function that takes two arrays as inputs and returns to us their intersection? Let's return the intersection in the form of an array.

Note that all elements in the final result should be unique. Here's one example:

const nums1 = [1, 2, 2, 1];
const nums2 = [2, 2];

intersection(nums1, nums2);
// [2]
Enter fullscreen mode Exit fullscreen mode

And here's another one:

const nums1 = [4,9,5];
const nums2 = [9,4,9,8,4];

intersection(nums1, nums2);
// [9, 4]
Enter fullscreen mode Exit fullscreen mode

This lesson was originally published at https://algodaily.com, where I maintain a technical interview course and write think-pieces for ambitious developers.


Brute Force

We'll start off slowly, by using the smallest sample inputs possible to examine the make-up of the problem. We know we'll need a result array to return, so hold that in mind:

const results = [];
Enter fullscreen mode Exit fullscreen mode

Let's say we need to find the intersection of two arrays: [1] and [1]. In this case, we know that the output is also [1]-- it's rather simple, because we just need to do a straight comparison of 1 and 1. We go through the first [1], see the 1, and locate it in the second array. Because they're the same, we just return a result with that match.

So we need to expand beyond this. Let's say the two inputs are modified to [1] and [2]. Well, when we compare the two single elements, we know that they're not the same. We thus don't need to do anything with result.

As this continues beyond one array element, we can continue this process of checking if each element in the first array exists in the second.


let intersection = firstArray.filter((el) => {
  return secondArray.includes(el);
};
Enter fullscreen mode Exit fullscreen mode

The concept of intersection is from set theory, so this problem is really simple if we just use Sets! In mathematics, the intersection of two sets A and B is the set that contains all elements of A that also belong to B.

Sets are an object type in most languages that allow you to store unique values of most primitives.

If we transform our input arrays into sets, we can make use of the filter method, and apply it to one of the sets-- filtering out anything not in the other set.

function intersection(nums1, nums2) {
  const set = new Set(nums1);
  const fileredSet = new Set(nums2.filter((n) => set.has(n)));
    return [ ...fileredSet ];
}
Enter fullscreen mode Exit fullscreen mode

This would have a time complexity of O(n).

The other way is to not use Sets and keep arrays to model the inputs. With that approach, we'll also need a hash Object to ensure uniqueness. This works because object keys must be unique.

We can collect unique intersections by doing an indexOf check and then returning it in array form:

function intersection(nums1, nums2) {
    let intersection = {};

    for (const num of nums1) if (nums2.indexOf(num) !== -1) intersection[num] = 1;

    return Object.keys(intersection).map((val) => parseInt(val));
}
Enter fullscreen mode Exit fullscreen mode

Despite there being two methods, it might be helpful to use the Set if you encounter a similar problem during your interview. This is because it demonstrates knowledge of a commonly used data structure and a background in mathematics.

Check out more visual tutorials for technical challenges at AlgoDaily.com and try out our daily coding problem newsletter!

Top comments (2)

Collapse
 
realdolos profile image
Dolores Greatamsky

The Set solution is not equivalent due to the filtered result being put through another Set, eliminating duplicates, while the plain filter+includes solution will return duplicates from the first array.

The indexOf solution shouldn't (ab)use an object as a hash map, and then parseInt, really, pretty please. People might copy that code, especially as it is last in your article.

My general purpose solution would be:

/**
 * Return elements present in both arrays, without duplicates
 */
function intersectWith(arr, other) {
  const known = new Set(arr);
  return other.filter(function(e) {
    if (!known.has(e)) {
      return false;
    }
    known.delete(e); // Avoid duplicates. Remove line if you want duplicates from other.
    return true;
  });
}

I like to avoid the conversation from array to another array (with filter) to a Set and back to array again ๐Ÿ˜

Collapse
 
codinglanguages profile image
Your DevOps Guy

Nice solution!

If the arrays are sorted, this problem can be solved in O(n) time and O(1) space (not including space for the actual intersection), using two pointers in a smart way.