Is this ES6 challenge solution supposed to be correct?

I was just doing the ES6: Use Destructuring Assignment to Assign Variables from Arrays challenge and the following code was accepted as correct:

I tried resetting all code a few times and re-entering the same solution and it still works even though it’s not using array destructuring to swap a and b as far as I can tell?

Well, you’ve managed to find a loophole in the tests: the code is quite clearly technically correct (it works fine!), but it’s definitely not what is supposed to be being taught. If possible, check the issues on GitHub, where the code for FCC is held, to see if someone else has noticed it, and if not, report it as an issue (note there’s a huge amount of issues, so may take a while.to get fixed I’m afraid), or if your feeling up to it, add a fix. Links here:

3 Likes

Wow. I’ve seen a lot of “bug reports”, but they usually are just user errors (I know, I made several). This is a legitimate one. I don’t know what exactly the test is looking for (perhaps no new variable declarations?), but it seems you’ve beaten it. And welcome to Test-driven-development :stuck_out_tongue: (seriously, though: the test just needs to be improved).

That being said, do you need help solving this the “in the spirit of the challenge”? I ask because I’ve seen this concept on “interview prep” stuff, and it’s pretty cool. Hint: When I took intro to CS, I learned that there was no way to swap the values of two variables without a third variable. ES6 syntax lets us skip the formal declaration of a “swap spot” by creating an array literal that is a “nameless” third object in memory.

3 Likes

There seems to be similar cases of the third test passing when it’s not supposed to reported on GitHub - freeCodeCamp/pull/34949. I’m not sure if I should report it as a new issue as they seem to be aware of it and I think they’re still working on a fix?

As for the challenge, unfortunately i stumbled across the solution others have used whilst checking why mine was accepted as correct. I have a few questions though, so thanks for offering to help :slight_smile:

Firstly, why does [a , b ] = [ b , a ]; work as a solution when the variables a and b were not declared as part of an array at the top of the program? Is that what you mean by ES6 syntax allowing us to create an array literal that is a “nameless” third object in memory? I tried a similar solution using const [ a, b ] = [ b , a ] following what was shown in the example, but it did not work. It was a bit confusing to me as to why I’m not dealing with an array in the challenge when that’s what the examples illustrate.

Secondly, I am a bit confused on whether the line “let a = 8, b = 6;” is considered as part of the function or not?

Excellent questions: I’ll answer the second first.

  1. Why does code inside the function know what a and b are?

Because the function was declared inside the same “scope” as a and b were, it has access to anything that was declared in the same scope (the top of the total program), and if it all the code in the editor window were enclosed in a block (denoted by curly braces), it would have access to that variable, too, like:

let c = 10;
{
  let a=8, b=6;
  (() => {
    a = 6;
    b = 8;
    c = 2;
  })();
}

Notice we see curly braces a LOT (around blocks of code we want to repeat in a loop, around blocks of code we want to be able to execute by name - aka functions, in if/else statements). The rule of thumb for block scoping is: “deeper blocks can access higher blocks, but not the other way around.”

  1. Don’t a and b have to be declared as part of an array?

No. You don’t “declare variables in an array”. An array is a type of value. Think of variables like buckets. You can put all sorts of stuff into buckets: water, sand, rocks, toys… these are the “values” that we “assign” to our variable buckets. In Javascript, any bucket can hold any type of value. There are primitive values undefined , null , boolean , string and number, and everything else including arrays are objects. You may want to park that “arrays are objects” in the back of your mind for now, because arrays are a special type of concept in comp sci which deserve their own discussion. An array is like a row of buckets:

Each bucket gets its own numerical index, which shows how far from the beginning it is. Inside each index we can store values which we call elements. In statically-typed languages like C++, the elements must all be the same type (integer numbers in the example above). In Javascript, every array bucket acts like a JS bucket, and so you can have a number at index 0, a string at index 1, and null at index 3 if you want. The whole array value is what gets assigned to a variable (numbers for the above array would be a good name). If we want to access individual buckets to get or set their values, we write the name followed by the index in square brackets, so numbers[3] would get us 17, and numbers[4] = 33 changes the value in element 4 from 22 to 33. We could also say numbers[5] = a;, and whatever value was stored in a would be copied into the bucket at index 5.

Notice that the array indices always run from 0 to array.length-1. There is a very good reason for this. JS is a high-level language, which keeps the details of the machine from you. In languages like C, you have to deal with the actual RAM of the computer, and ask for a whole contiguous block of memory to store the entire unbroken array. You also just know that the array has a certain location for the first element (the pointer to the array - this will be important later), and if you want to access other elements, you move over from there (see picture below for an array of characters - strings of length 1). The memory location of each element is the location of the beginning of the array + index of the element we want. THIS is why arrays start at 0.

Whew. Take five, smoke 'em if you got 'em. With that understanding of arrays and variables out of the way, there are several ways to make a new array in Javascript, some of which are below.

let arr1 = Array(5);// five empty slots [0 thru 4], not even "undefined" - just empty
let arr2 = [1, null, "Hello, World!", undefined, ["arrays can be values, too"]]; //five slots, all different types.

The latter way is called an “array literal” because you literally describe each element. When you write the code below, you get a new array literal, the only thing you did different from the code above is to have Javascript lookup the value in a and b before assigning those values as elements in the array. The values in the array are now copies. I can change them without affecting what’s in a or b because primitives get passed by value (a copy is sent) and objects get passed by reference (a copy of the pointer (see paragraph on arrays in C above) is sent.

let arr3 = [b, a]; //just another array literal

The final piece of the puzzle is the whole code:

// WRONG: "let [a, b] = [b, a]." - a and b are already declared
// we don't need to make more room in RAM for them,
// we just need to fill those RAM buckets with new values.

/*CORRECT code below:*/
[a, b] = [b, a];

What’s happening here is that a new array literal [6, 8] is being created (because those were the values of b and a, respectively when it was created. Notice that we have created a THIRD VALUE without giving it a name. Now that the value returned from the right-hand side of the assignment operator, =, is known, we can assign that value to the variable listed on the left. Because of the very clever ES6 destructuring syntax, instead of assigning it to a variable (like in our arr3 example above), we are breaking the array up into its elements (destructuring it) and assigning it to multiple variables we have listed in the places of the elements we want to assign to each. So, now our namelessArray[0] element (6, a copy of what b was at the time the “nameless array” was created) gets assigned to a, and our namelessArray[1] element (8, a copy of what a used to be) gets assigned to b. So, without naming a third variable, Javascript created a third AND fourth space in RAM, and used those to swap it. But from the code, only two variables were ever declared.

See you next week, class. Homework is on the homepage, your TA has office hours on Wednesday, and your group projects are due on Friday.

2 Likes

Haha, thanks a lot for the thorough explanation :slight_smile: Helps a ton!

1 Like