FreeCodeCamp -Refactor Global Variables Out of Functions

FreeCodeCamp -Refactor Global Variables Out of Functions
0
#1

Hello, i don’t really need help but i struggled a bit at this exercice.

To do the exercice you have to know how slice() work when doing a copy (called shallow copy) of an array passed in a function argument.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice

``````/*
*/

// the global variable
var bookList = ["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"];

//function add a book to the array
function add( bookList, bookName ) {
//make a copy of the argument's array
let bookListCopy = bookList.slice(0);
//add the bookName to the new array
bookListCopy.push( bookName );

//return the new modified array
return bookListCopy;
};

//function remove a book from the array
function remove( bookList, bookName ) {
//make a copy of the argument's array
let bookListCopy = bookList.slice(0);

if( bookListCopy.indexOf( bookName ) >= 0 ) {
//delet the book
bookListCopy.splice( bookListCopy.indexOf( bookName ), 1 );

//return the new modified array
return bookListCopy;
}
};

//create a new array from an already existing one but with a new bookName in it
var newBookList = add( bookList, 'A Brief History of Time' );

//create a new array from an already existing one but with a deleted bookName from it
var newerBookList = remove( bookList, 'On The Electrodynamics of Moving Bodies' );

//remove from the bookList at which we added 'A Brief History of Time', the bookName 'On The Electrodynamics of Moving Bodies'
var newestBookList = remove( newBookList, 'On The Electrodynamics of Moving Bodies' );

//["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"];
console.log( bookList );
//["The Hound of the Baskervilles", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"]
//["The Hound of the Baskervilles", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae", "A Brief History of Time"]
``````

13 Likes

#2

There is a bug on this exercice

Function remove() should not use splice() this way, it adds the bookName to the begining of the array, instead or removing it.

``````return bookList.splice(0, 1, bookName);
``````

The exercice is about refactoring the code to stop altering the global array. If it’s not a bug and the mistake in remove() is made on purpose to make the exercise more challenging this is very confusing

EDIT

Aw look like the issue is known for a long time

3 Likes

#3

^bump

Thank you for this post. This exercise is extremely confusing. Example and instructions don’t match what you have to do.

4 Likes

#4

Thank you for this post.
In addition, I wanted to set an internal variable to equal to the list by using:
function add ( list, bookName) {
var a = list;
a.push(bookName);
}
It appears that I have to use the slice function to create a copy of the bookList.

0 Likes

#5

Thank you @pocahontas123 for pointing out this. I never knew that there was anything like “Deep-copying” an array. Now i learnt alot about it. Another reference to this topic is here :

3 Likes

#6

My function add looks like this:

return bookList.concat(bookName);
}

concat() function does not change existing array.

2 Likes

#7

var a =[…list];//this will creates the copy of array

2 Likes

#8

yes there is bug in splice method in this exercise !
but finally i came up with this solution

function remove (books, bookName) {
let BL =[…books];
if (BL.indexOf(bookName) >= 0) {

``````  let bl=[];
BL.map((a,i)=>{
if (a!=bookName) {
bl.push(a);
}
});
return bl;

}
``````

}

4 Likes

#9

OxiBo
Brilliant. What about the remove function, how did you handle it?
Hope you have a clean solution like the concate function.

0 Likes

#10

It’s confusing but if you read the instructions you’ll understand that it’s asking you to convert the code so that (a) functions should not mutate the global array “bookList” and (b) both functions should return an array . Following what we’ve studied so far (including debugging) you can create a new array variable inside the functions and copy the existing array on it using […array] and after performing the required tasks on it, return the new array. the remove function seems to have a bug either intentionally or not but you can easily figure out and fix it since the value splice needs for index should be equal to the index of the input variable.

let arrNew = […arr];
arrNew.push(bookName);
return arrNew;
}

function remove (arr, bookName) {
let arrNew = […arr];
if (arrNew.indexOf(bookName) >= 0) {

``````arrNew.splice(arrNew.indexOf(bookName), 1);

}
``````

return arrNew;
}

1 Like

#11

Hello campers ,here is my solution after being so confused about what method should I use :

``````// the global variable
var bookList = ["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"];

/* This function should add a book to the list and return the list */
// New parameters should come before the bookName one

function add (newArr,bookName) { //newArr is the new parameter mentionned above
let sliced=newArr.slice(0,); // I have sliced  newArr for copying booklist array
sliced.push(bookName); // now I push the string
return sliced; // finally I returned the sliced array by the way slice method does not change the origine array

}

/* This function should remove a book from the list and return the list */
// New parameters should come before the bookName one

function remove(newArr,bookName) {//here is the same thing as above
let slicedTwo=newArr.slice(0,); //also here
if (slicedTwo.indexOf(bookName) >= 0) {// here if the condition is true means that the slicedTwo has the string I am looking for
let index=slicedTwo.indexOf(bookName); //here I want to know the index where this string is living

slicedTwo.splice(index,1); // I use splice method to extract it from my array and this method changes the origine array
return slicedTwo; //now I return the splicedTwo array
};
}

var newBookList = add(bookList, 'A Brief History of Time');
var newerBookList = remove(bookList, 'On The Electrodynamics of Moving Bodies');
var newestBookList = remove(add(bookList, 'A Brief History of Time'), 'On The Electrodynamics of Moving Bodies');

console.log(bookList); //here bookList is not changed because I have made a copy of it .

//"A Brief History of Time"
``````
0 Likes

#12

Hi,

I went with:

var temp = […a];
temp.push(s);
return temp;
}

/* This function should remove a book from the list and return the list */
// New parameters should come before the bookName one

function remove (a, s) {
var temp = […a];
if (temp.indexOf(s) >= 0) {
temp.splice(temp.indexOf(s), 1);
console.log(temp);
return temp;
}
}

If someone could explain why spreading a […a] is needed here i’d very much appreciate it as i’d like to understand destructuring better. Thankyou

1 Like

#13

This was so confusing! This is what I finally put together. I hope they get it fixed soon.

let copy = […bookList]
copy.push(bookName);
return copy;
}

/* This function should remove a book from the list and return the list */
// New parameters should come before the bookName one

function remove (bookList, bookName) {
let copy = […bookList]
let pos = copy.indexOf(bookName);
if (pos >= 0) {

``````copy.splice(pos, 1);

0 Likes

#14

Here is my working solution

``````// the global variable
var bookList = ["The Hound of the Baskervilles", "On The Electrodynamics of Moving Bodies", "Philosophiæ Naturalis Principia Mathematica", "Disquisitiones Arithmeticae"];

/* This function should add a book to the list and return the list */
// New parameters should come before the bookName one

let copyBookList = [...arr];

copyBookList.push(bookName);

return copyBookList;

}

/* This function should remove a book from the list and return the list */
// New parameters should come before the bookName one

function remove (arr, bookName) {

let copyBookList = [...arr];

if (copyBookList.indexOf(bookName) >= 0) {
copyBookList.splice(copyBookList.indexOf(bookName), 1);

return copyBookList

}
}

var newBookList = add(bookList, 'A Brief History of Time');
var newerBookList = remove(bookList, 'On The Electrodynamics of Moving Bodies');
var newestBookList = remove(add(bookList, 'A Brief History of Time'), 'On The Electrodynamics of Moving Bodies');

0 Likes

#15

i agree with you

0 Likes

#16

I finally figured out the problem. The one thing that was tripping me out was that I was trying to copy the argument to a variable like this

``````let copyBookList = arr; //Which led to indexOf not a function
let copyBookList = [...arr] //This finally let me pass my tests
``````

One thing That I still don’t understand is that why the former code wasn’t able to let me use indexOf but rather the latter one.

0 Likes

#17

Sir I salute you for fixing this challange. See if you can fix this challange https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/es6/create-strings-using-template-literals. It is bugged just like this challange so meaby you can fix this as well.

0 Likes

#18

I’m getting the error .indexOf() is not a function - it happens ONLY when testing the newestBookList variable on the console. I have no idea why.

My code is:

// the global variable
var bookList = [“The Hound of the Baskervilles”, “On The Electrodynamics of Moving Bodies”, “Philosophiæ Naturalis Principia Mathematica”, “Disquisitiones Arithmeticae”];

/* This function should add a book to the list and return the list */
// New parameters should come before the bookName one

let newList = list.push(bookName);
return newList;

}

/* This function should remove a book from the list and return the list */
// New parameters should come before the bookName one

function remove (list, bookName) {
if (list.indexOf(bookName) >= 0) {

``````let i = list.indexOf(bookName);
let a = list.slice(0,i);
let b = list.slice(i+1, list.length-1);
let newList = a.concat(b);
return newList;
``````

}
}

var newBookList = add(bookList, ‘A Brief History of Time’);
var newerBookList = remove(bookList, ‘On The Electrodynamics of Moving Bodies’);
var newestBookList = remove(add(bookList, ‘A Brief History of Time’), ‘On The Electrodynamics of Moving Bodies’);

console.log(bookList);
console.log(newBookList);

0 Likes

#19

returning a computation tripped me up

Worked:
copiedList.push(bookName);
return copiedList;

Nope:
return copiedList.push(bookName);

same in removed function i just removed any operations from the return statement and got a green checkmark
why this is is beyond me

3 Likes

#20

Thanks mate for your awesome solution

0 Likes