Rest operator & array comparison

Tell us what’s happening:
Describe your issue in detail here.
Hello,
I am trying to use the rest operator in this challenge but I don’t know how I would compare the arguments to the array values. Any hints?

  **Your code so far**

function destroyer(arr, ...args) {
for(let i = 0; i < arr.length; ++i) {
  if(arr[i] == args) arr.splice(i, 1);
}
console.log(arr)
return arr;
}

destroyer([1, 2, 3, 1, 2, 3], 2, 3);
  **Your browser information:**

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36

Challenge: Seek and Destroy

Link to the challenge:

You have to know what’s your inputs and what’s your outputs.
What is args? have you console.log it?
What is splice method? What is the output of splice method?

Once we know the inputs and the outputs (is it a string? array? number?), for sure we can narrow down the search of what methods we have to use to solve the problem

Check MDN (Mozilla Developer Network).

Just in case you haven’t realized. We can debug FCC problems by copy pasting whatever specs on the left column to the space under our function, and console.log them. Like this:

function destroyer(arr, ...args) {
for(let i = 0; i < arr.length; ++i) {
  if(arr[i] == args) arr.splice(i, 1);
}
console.log(arr)
console.log(args)
return arr;
}

destroyer([1, 2, 3, 1, 2, 3], 2, 3) //should return [1, 1].
destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3) //should return [1, 5, 1].
destroyer([3, 5, 1, 2, 2], 2, 3, 5) //should return [1].
destroyer([2, 3, 2, 3], 2, 3) //should return [].
destroyer(["tree", "hamburger", 53], "tree", 53) //should return ["hamburger"].
destroyer(["possum", "trollo", 12, "safari", "hotdog", 92, 65, "grandma", "bugati", "trojan", "yacht"], "yacht", "possum", "trollo", "safari", "hotdog", "grandma", "bugati", "trojan") //should return [12,92,65].

If it’s too much, you can comment out all of them except one to work on.

Splice is indeed remove an element in an array.

1 Like

I had to get help from the solutions to convert args to an array, although, I still have some questions about how it works. In the solution, it was using slice(1) but my code worked when I changed it to 0. What does .values do here and why does slicing at index 0 convert it to an array?
Also, at this point, my code works for some of the test cases but fails some others and I don’t see the reason. I would appreciate any help. Thank you!

function destroyer(arr, ...args) {
  let valsToRemove = Object.values(args).slice(0);
  console.log(valsToRemove.length);
  for(let i = 0; i < arr.length; ++i) {
    for(let j = 0; j < valsToRemove.length; ++j) {
      if(arr[i] == valsToRemove[j]) arr.splice(i, 1);
    }
    }
  console.log(arr);
  console.log(valsToRemove);
  return arr;
}

destroyer([2, 3, 2, 3], 2, 3);

You did not notice from the console.log, what args is. By definition, rest parameter grabs everything that has not been captured by the function parameter, and put them in an array.

You can see in the console.log, args is already an array. You don’t need Object.values().
While array is also an object, Object.values() is a static method specific for a Plain Old Javascript Object (POJO), which is to grab all the values from an object (that’s suppose to have key-value pairs) and serve those values only in an array.

Try looking at it again. You’re close. Here I show you how to debug with console.log. Copy paste it. This way we could visualize how the stack process work, how JS read your code.

Try it. If you still stuck, ask again.

function destroyer(arr, ...args) {
  let valsToRemove = Object.values(args).slice(0);
  for(let i = 0; i < arr.length; ++i) {
    let num = arr[i];
    for(let j = 0; j < valsToRemove.length; j++) {
      let toremove = valsToRemove[j]
      console.log(["i: " + i, "j: " + j, "num: "+ num, "toremove: "+ toremove])
      console.log(["num == toremove? ", num == toremove])
      if(arr[i] == valsToRemove[j]) {
        arr.splice(i, 1);
      }
      console.log("arr: " + arr)
    }
    }
 // console.log(arr);
 // console.log(valsToRemove);
  return arr;
}



// destroyer([1, 2, 3, 1, 2, 3], 2, 3) //should return [1, 1].
// destroyer([1, 2, 3, 5, 1, 2, 3], 2, 3) //should return [1, 5, 1].
destroyer([3, 5, 1, 2, 2], 2, 3, 5) //should return [1].
destroyer([2, 3, 2, 3], 2, 3) //should return [].
// destroyer(["tree", "hamburger", 53], "tree", 53) //should return ["hamburger"].
destroyer(["possum", "trollo", 12, "safari", "hotdog", 92, 65, "grandma", "bugati", "trojan", "yacht"], "yacht", "possum", "trollo", "safari", "hotdog", "grandma", "bugati", "trojan") //should return [12,92,65].
1 Like

Okay, I managed to pass the challenge by changing the code a little bit and not using splice. Was the reason why this code was failing because splice was modifying the original array so that arr[i] was not showing the values in the order they appeared in the original one?

most likely, slice and splice might be very similar on spelling, but they are very different as behavior and you must make the difference when working with the two. They not only behave different with the arrays, but they also accept different parameters.

It doesn’t seem to me that the problem was confusing splice and slice because I was really trying to achieve what splice was doing here, however, for example, arr[1] was not pointing to the second element of the original array for some test cases which made me think that this occurred due to splice mutating the original array.

How did you solve it? I’m legit curious. If you can show me your code?

Input: two arrays, arr and args;
Output: original array, modified (removed elements);
Constraint: none.

To check whether an element is in an array, yes we can do double loop;

There are a few array methods to modify an array, e.g. push, pop, shift, unshift and splice. But only splice can remove an element in the middle of an array. So I’m wondering what did you use.

Your code failed because once we removed an element from the middle of an array with .splice() (or from the beginning of an array with .shift()), all the elements that come after that removed element shifted, thus their index changed.

Because your iteration keep moving one step forward (i++) although due to .splice() operation the next element has been shifted (from previously the index is i + 1, but now became i), your iteration skipped over that element unchecked. This is very obvious if you observed thoroughly the console.log result of code blocks I gave you.

To compensate for that we have to tweak our IF statement. If the condition is True, do splice(), and instead of doing the next iteration (i++), let’s continue the checking with i for the rest of element in args. That could be done with i-- or i = i - 1 (to . And because we work with double loops, the same thing must be done with j.

      if(arr[i] == valsToRemove[j]) {
        arr.splice(i, 1);
        i--;
        j--;
      }

That’s why I said you’re close. You only need 2 lines to make the function pass.

Btw, array.slice(0) slash no element in that array, but creates a new array with same elements. It did nothing in your code except making a copy of Object.values(). This is easily verified by comparing console.log(args) and console.log(valsToRemove)

1 Like

Here is my solution:

function destroyer(arr, ...args) {
  let valsToRemove = Object.values(args).slice(0);
  for(let i = 0; i < arr.length; ++i) {

    for(let j = 0; j < valsToRemove.length; j++) {
      
      if(arr[i] == valsToRemove[j]) {
        delete arr[i]
      }
    }
    }
 console.log(arr);
 let newArr = arr.filter(val => val != undefined);
 console.log(newArr);
  return newArr;
}

destroyer(["possum", "trollo", 12, "safari", "hotdog", 92, 65, "grandma", "bugati", "trojan", "yacht"], "yacht", "possum", "trollo", "safari", "hotdog", "grandma", "bugati", "trojan") 

I observed the console.logs and figured that there is something not working the way I wanted with the array indexes but I though fixing it would be much complicated , like storing the original array multiple times etc. Thank you for your help and posting the modification needed!

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.