What is this function doing with the array/object? Cannot figure out why?

// This is the function I can not figure out:
function containsAll(arr) {  // arguments keyword is object built into javascript
  for (let k = 1; k < arguments.length; k++) {
    let num = arguments[k];
    if (arr.indexOf(num) === -1) {
      return false;
    }
  }
  return true;
}

 let x = [2, 4, 6, 7];
console.log(containsAll(x, 2, 4, 7)); // true
console.log(containsAll(x, 6, 4, 9));  // false

Question: I think its taking the first index item of the array, the array in arguments[0], and comparing to see that it matches other entries in the x array. I don’t see how its possible given the function. Need some clarity. Thanks

In order to understand what’s going on here let’s break down the keywords arguments and .indexOf().

arguments
This “turns” the parameter passed into the function to the format of an array.

.indexOf()
This will return the index at which the first element of an array equals the parameter passed to indexOf().
In case none is found it returns -1. However it will return a number.

For the sake of this explanation I will assume your example variable let x = [2, 4, 6, 7]; will be passed as a parameter to the function with the additional numbers 2, 4, 7 like so:
containsAll(x, 2, 4, 7);

Breaking down your function, it will return true by default:

function containsAll(arr) { 
  ...
  return true;
}

The for loop in it will run an if statement each circle. Note: The default “true” will only be returned in case the for loop statement is failing on every circle. This might be a bit counter intuitive but bear with me for now.

Let’s look at the for loop:

  for (let k = 1; k < arguments.length; k++) {
    let num = arguments[k];
    if (arr.indexOf(num) === -1) {
      return false;
    }
  }

(let k = 1; k < arguments.length; k++) Is starting at k = 1, and running until the length value of the parameter given to the function (handled as an array) is reached. The parameter passed to the function is arguments (x, 2, 4, 7) and looks like this now (multidimensional array):

[[2, 4, 6, 7], 2, 4, 7]

Next up is:

let num = arguments[k];

k is used as the index to check the arguments array at, note that it starts at 1 by default so the first index to be checked when k is passed for an index will never be 0 (the actual first index of the array). That means whatever is passed to the function containsAll() as the first parameter will never be stored in the let num part on any circle of the loop.

Here is what the num variable will hold in this example:
1st circle: 2
2nd circle: 4
3rd circle: 7

basically it will loop through all parameters passed to the containsAll() function that follow the first parameter(in our example: x -> containsAll(x, 2, 4, 7)).

What is the if statement doing?

if (arr.indexOf(num) === -1) {}

It’s taking the whole parameter passed into the function “[2, 4, 6, 7], 2, 4, 7” (arr) while not assuming it’s a multi dimensional array (note that it takes arr, not arguments which would make it a multi dimensional array instead) and runs indexOf() on it.

This, however, means it(.indexOf()) can only work with the array part given to the function at the first index of the parameter: containsAll(>ARRAY HERE<, 2, 4, 7), which in turn means the variable x in this example must be an array or else the function will not work to begin with.

Then indexOf(num) checks whether the current num value (see above what num holds each circle) is found in the array (passed as x) and - back to what the if statement is looking for - the if statement checks whether indexOf() ever returns -1 ("=== -1") which it will only do in case num is NOT found in the array x.

Once the loop finishes and -1 is never returned by indexOf() because all the numbers passed into indexOf() are also found in the provided array (x in our case) it defaults back to return true.

In case indexOf() returns -1 because the parameter it is asked to look for in the source array (x of arr in this example) is not found it thereby found what the if statement was looking for. Therefore returning true to the statement itself which will in turn execute return false. This is kind of counter intuitive at first glance.

I hope this helps.

1 Like

It’s important to note that when there are named parameters, they are assigned the values from the arguments object, which is how arr ends up being [2, 4, 6, 7].