Start learning free

LESSON 237 OF 671 · SETS

Only in the First Array in JavaScript with Sets

Practice Read the full explanation

You get two arrays of integers, a and b.

Return a new array with the values of a that are not in b.

Each value goes into the result only once. Keep the values in the order they first appear in a.

If every value of a is also in b, return an empty array.

 

Example 1:

Input: a = [1, 2, 3, 4], b = [2, 4]
Output: [1, 3]
Explanation: 2 and 4 are in b, so they are left out.

Example 2:

Input: a = [5, 6, 5, 7], b = [7]
Output: [5, 6]
Explanation: 7 is in b.
5 appears twice in a, but only once in the result.

Example 3:

Input: a = [1, 2], b = [2, 3, 1]
Output: []
Explanation: Both values of a are also in b, so nothing is left.

 

Constraints:

  • a and b each have at least one number.
  • Every number is between -109 and 109.
STEP 1 OF 8
    Ctrl + Enter to check

    JAVASCRIPT · SETS

    Only In First in JavaScript, explained

    Problem overview

    The method onlyInFirst gets two arrays of integers, a and b, and returns a new array with the values of a that are not in b. Each value goes into the result once, in the order it first appears in a. If every value of a is also in b, the result is an empty array.

    For a = [1, 2, 3, 4] and b = [2, 4] the answer is [1, 3]. For a = [5, 6, 5, 7] and b = [7] the answer is [5, 6]: 7 is in b, and 5 appears twice in a but only once in the result. For a = [1, 2] and b = [2, 3, 1] the answer is empty.

    Approach

    There are two questions for each number of a: is it in b, and is it already in the result? Both are membership questions, and a Set answers them fast. So the plan uses two sets. setB holds the values of b, where repeats collapse into one. seen holds the values already put in the result, so a repeat in a doesn't go in twice.

    A number is added to the result only when both checks say no. Reading a from left to right keeps the order of first appearance.

    Step by step

    1. Build setB from b with new Set(b).
    2. Create seen, an empty set for the values already in the result.
    3. Create result, an empty array.
    4. Loop over a with for (let num of a).
    5. Check both conditions joined by &&: !setB.has(num) (b doesn't have it) and !seen.has(num) (it isn't in the result yet). Both must be true.
    6. Push num onto result.
    7. Add num to seen, so a later copy is skipped.
    8. Return result after the loop. It can be empty.

    The solution in JavaScript

    class Solution {
        onlyInFirst(a, b) {
            let setB = new Set(b);
            let seen = new Set();
            let result = [];
            for (let num of a) {
                if (!setB.has(num) && !seen.has(num)) {
                    result.push(num);
                    seen.add(num);
                }
            }
            return result;
        }
    }
    

    The operator && stops as soon as the left side is false, so a number that is in b never reaches the seen check. Either order of the two checks gives the same result.

    Another way

    Another way to write it removes the repeats of a first and then filters. A set built from a already drops later copies and keeps the first-appearance order, so only the b check is left:

    function viaSet(a, b) {
        const inB = new Set(b);
        return [...new Set(a)].filter(num => !inB.has(num));
    }
    

    It returns 1 3, 5 6 and an empty array on the three examples. The lesson's loop does the same work in one pass and shows each set's job on its own line.

    Testing

    On the three examples the solution prints these lines:

    1 3
    5 6
    

    followed by an empty line for the third example, because an empty array prints as nothing.

    Common mistakes

    • Forgetting seen. Keeping only the values of a that aren't in b is a one-liner with filter, but on the second example it gives 5 6 5: the repeat of 5 comes through.
    • Using the array b directly with includes. It works, but it looks at the values of b one by one for each number of a. A set checks in one step.
    • Checking the wrong array. The values to keep are the ones missing from b. Values that appear only in b never matter.
    • Returning inside the loop, which would end after the first value.
    Keep going with JavaScript500+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free