JavaScript Array Manipulation: Issues with forEach

When i want to modify an array like below, it doesn't modify the original array. Why is that?
let gameBoard = Array(3)
.fill()
.map(() => Array(3).fill("X")); //Create 2D Array

const resetGameBoard = () =>
gameBoard.forEach((arr, index) => {
console.log(arr === gameBoard[index]); // this shows they are the same object?

console.log(arr.map((item) => item = ""));
arr = arr.map((item) => item = "");
});

resetGameBoard();
console.log(gameBoard);
let gameBoard = Array(3)
.fill()
.map(() => Array(3).fill("X")); //Create 2D Array

const resetGameBoard = () =>
gameBoard.forEach((arr, index) => {
console.log(arr === gameBoard[index]); // this shows they are the same object?

console.log(arr.map((item) => item = ""));
arr = arr.map((item) => item = "");
});

resetGameBoard();
console.log(gameBoard);
If i change the arr = arr.map((item) => item = ""); to gameBoard[index] = arr.map((item) => item = ""); it works as expected and modify the original array. What is the difference here?
130 Replies
13eck
13eck4mo ago
Array.map() creates and returns a new array, it does nothing to the original. Array.forEach(), on the other hand, doesn’t create a new array or return any value. Instead, it performs a function on each value inside the array. Also, the forEach() method takes a function that has the item and index, not the array and index
const resetGameBoard = () =>
gameBoard.forEach((item, index) => {
console.log(item === gameBoard[index]);
const resetGameBoard = () =>
gameBoard.forEach((item, index) => {
console.log(item === gameBoard[index]);
So of course the item will be the same as the gameBoard[index] :p
FF
FFOP4mo ago
Yes, know that but, my logic is that arr is an object that has a reference to an array (depends on the index) inside the gameBoard so, i think i can change it but, this isn't the right logic it seems. I'm confused with arr here actually.
13eck
13eck4mo ago
What exactly are you trying to do? Your code is a bit confusing so I’m not sure what the current results are vs what want them to be Also, what does an item in your game board array look like?
FF
FFOP4mo ago
I want to change the array. This array has three sub arrays and i want to access all of them and change their values to "". So, i thought if i forEach the gameBoard array; arr parameter gives me arrays inside gameboard Arrays and i can change this arrays. Sorry, if i misleading you to wrong direction and gameBoard array is 2D array. it has 3 arrays inside it and they have 3 empty strings I will change to my phone because i will go to my home but, i want to talk about it if you have time.
ἔρως
ἔρως4mo ago
is this for tictactoe?
FF
FFOP4mo ago
yes
ἔρως
ἔρως4mo ago
why dont you use a single flat array?
FF
FFOP4mo ago
actually, i dont know. You are right about it 🙂 but, i want to know why this behaviour happens though
13eck
13eck4mo ago
If you’re resetting everything why do a recursive search? Why not just set the main game board to a new, empty/reset array?
ἔρως
ἔρως4mo ago
^ also, foreach doesnt update the array values
FF
FFOP4mo ago
Yes guys, you are right about your implementations and mine is bad i know it. I just wonder why in this situation JS behaves like that
ἔρως
ἔρως4mo ago
you are updating a local variable inside a foreach and that's it the value will be lost it behaves like that because foreach is the wrong tool
FF
FFOP4mo ago
But why gives true when i check the equality between them
ἔρως
ἔρως4mo ago
copy on write? i think v8 uses that
13eck
13eck4mo ago
Arrays are shallow copies, so you’re comparing, in essence, the exact same thing
FF
FFOP4mo ago
when we compare arrays isnt it comparing reference value on memory? sorry i dont understand
ἔρως
ἔρως4mo ago
copy on write it copies when you write into the shallow clone or reference
FF
FFOP4mo ago
probably my knowledge isnt quite good about this topic, i will research it
ἔρως
ἔρως4mo ago
Edit fiddle - JSFiddle - Code Playground
Test your JavaScript, CSS, HTML or CoffeeScript online with JSFiddle code editor.
ἔρως
ἔρως4mo ago
check that you will see it shows true then false wait, i was right and wrong map returns a new array it wont update the old array
FF
FFOP4mo ago
yes
ἔρως
ἔρως4mo ago
in essence, you are changing a local variable
13eck
13eck4mo ago
When comparing an array I believe it compares each item in the array and checks the memory address for complex objects, or discrete values for primitives, ands if any are different they’re not considered equal
ἔρως
ἔρως4mo ago
its an object, so, its compared by reference reference is the same? then it's true different references are false, even with the same elements
FF
FFOP4mo ago
thats the confusing part for me actually
ἔρως
ἔρως4mo ago
[] is not the same as []
13eck
13eck4mo ago
If a reference contains another reference it has to compare each inner reference
ἔρως
ἔρως4mo ago
comparing both is always false
FF
FFOP4mo ago
and when we pass arguments as an object to function, parameter is a local variable of course but it still holds a reference right?
13eck
13eck4mo ago
Array methods create shallow copies, which is a reference to the actual object yes
ἔρως
ἔρως4mo ago
nope
No description
ἔρως
ἔρως4mo ago
but when you assign a nee array, it doesnt reference the old value anymore
13eck
13eck4mo ago
Cool, thanks for checking. In on my phone waiting at work so I’m going off of memory here
ἔρως
ἔρως4mo ago
you're welcome js is complicated
FF
FFOP4mo ago
no worry guys at least you have a memory my brain melts rn 😃
ἔρως
ἔρως4mo ago
let me draw it for you then
FF
FFOP4mo ago
yes js is confusing
13eck
13eck4mo ago
Now do: d.forEach( (item, idx) => console.log(item === c[idx]) ); That’s gonna be true for both, IIRC
FF
FFOP4mo ago
yes because it has the same reference?
ἔρως
ἔρως4mo ago
yes
13eck
13eck4mo ago
Indeed
ἔρως
ἔρως4mo ago
but when you assign item.map, it received a new array
FF
FFOP4mo ago
yes and then i returned the new array to arr wich didnt work
ἔρως
ἔρως4mo ago
foreach doesnt do anything with returns the value is ignored
13eck
13eck4mo ago
Whelp, time to actually work. Have fun, y’all! :x13ladWave:
FF
FFOP4mo ago
good time my man thank you
ἔρως
ἔρως4mo ago
map will update the value in the array, foreach wont do anything returning a value is like tossing it into a void
FF
FFOP4mo ago
it doesnt update it returns a new array
ἔρως
ἔρως4mo ago
not foreach
FF
FFOP4mo ago
yes foreach doesnt return anything
ἔρως
ἔρως4mo ago
map updates the value on a shallow copy of the array
FF
FFOP4mo ago
as far as i know it creates a new array with given callback function doesnt mutate the original one
ἔρως
ἔρως4mo ago
neither of those is true this is what it does as far as i know
FF
FFOP4mo ago
Can you look it up on mdn
ἔρως
ἔρως4mo ago
you are right
FF
FFOP4mo ago
because i am phone i cant give a link my phone is slow as hell
ἔρως
ἔρως4mo ago
it creates a new array not a shallow copy
FF
FFOP4mo ago
yes
ἔρως
ἔρως4mo ago
that sounds inneficient
FF
FFOP4mo ago
what do you mean with shallow copy actually isnt it a primitive and object values combined
ἔρως
ἔρως4mo ago
a shallow copy is when you copy a value, but keep the references of the other elements in the object
FF
FFOP4mo ago
hmm
ἔρως
ἔρως4mo ago
for example, you have x = [] now you create y = [x]
FF
FFOP4mo ago
it is a reference right to x in the array
ἔρως
ἔρως4mo ago
if you clone y into z, then y[0] and z[0] will reference x thats a shallow clone, shallow copy or whatever
FF
FFOP4mo ago
yes
ἔρως
ἔρως4mo ago
there are many names a deep clone or copy will also clone x, and will clone all the values in x
FF
FFOP4mo ago
shallow copy is an object with objects then right
ἔρως
ἔρως4mo ago
not exactly
FF
FFOP4mo ago
hmm my brain failing me today
ἔρως
ἔρως4mo ago
you create a new object, but any references in it aren't copied they still reference the object
FF
FFOP4mo ago
hmm
ἔρως
ἔρως4mo ago
a deep copy goes deep and copies everything imagine you have x = []
FF
FFOP4mo ago
yes
ἔρως
ἔρως4mo ago
and then you create y = [x] the first element of y is a reference to x, right?
FF
FFOP4mo ago
yes and x is an object
ἔρως
ἔρως4mo ago
it's an array, but yes so, a shallow copy is the same as doing [x] again a deep copy is the same as doing [[]] if x = [12345] then a shallow copy is still just another [x] but a new deep copy is [[12345]]
FF
FFOP4mo ago
hmm as far as y is concern x's actual value isnt important because they are pointing the same block on memory?
ἔρως
ἔρως4mo ago
No description
ἔρως
ἔρως4mo ago
this is a shallow vs deep copy
FF
FFOP4mo ago
deep copy is another object then but shallow is same
ἔρως
ἔρως4mo ago
no, always a new one notice how the right side is purple instead of yellow
FF
FFOP4mo ago
oooo shallow copy is another object but if it has objects to reference they dont bother to copy them
ἔρως
ἔρως4mo ago
it keeps the same reference
FF
FFOP4mo ago
yes
ἔρως
ἔρως4mo ago
the deep copy will copy the object it is referencing
FF
FFOP4mo ago
thats why i said object in object but you said it wrong how yes if it is primitive
ἔρως
ἔρως4mo ago
i said it was an array, in the example, because the prototype is different but an array is an object, but an object isnt an array
FF
FFOP4mo ago
yes
ἔρως
ἔρως4mo ago
no, no. a deep copy will copy EVERYTHING
FF
FFOP4mo ago
because arrays prototype is object
ἔρως
ἔρως4mo ago
the prototype of the array prototype is object
FF
FFOP4mo ago
yes i understand but if it has objects then it cant do that right because it holds reference then yes sorry and in prototype chain there will be object.prototype Thank you for taking your time man i dont want to bother you because of this nonsense that i dont understand but it was a nice conversation
ἔρως
ἔρως4mo ago
No description
ἔρως
ἔρως4mo ago
and now, does it make sense? notice how the x isnt x at the bottom you're not bothering, but, you're welcome
FF
FFOP4mo ago
yes i understand that actually but "hello" needs to be deep copied right? on the top one
ἔρως
ἔρως4mo ago
it is always deep copied because its a scalar value
FF
FFOP4mo ago
thanks mate can i add you as a friend. i will read an articles about what mentioned then we can talk with more knowledge but, there is one issue i still didnt understand my first local variable question and i didnt find a good answer on the internet. Maybe i need to research it a little bit more
ἔρως
ἔρως4mo ago
finally managed to send a proper copy
ἔρως
ἔρως4mo ago
this is a much more readable version
FF
FFOP4mo ago
thanks very appreciate it
ἔρως
ἔρως4mo ago
nothing personal, but i would prefer not to. ive rejected that others add me. i want to avoid coming to discord and not being able to use it because people are always asking stuff in private
FF
FFOP4mo ago
Okay, not a problem. You have the right to do so
ἔρως
ἔρως4mo ago
you can ping me here, in this channel
FF
FFOP4mo ago
Thank you
ἔρως
ἔρως4mo ago
you're welcome. if you want to do stuff like that, or edit it, use excalidraw just upload the svg there and you have everything editable
FF
FFOP4mo ago
it is a good one Okay, i will keep in mind
ἔρως
ἔρως4mo ago
it is, and it is very simple and easier to use than paint
FF
FFOP4mo ago
i have used it actually straight to the point one
ἔρως
ἔρως4mo ago
i use it a lot
FF
FFOP4mo ago
you have any interest in graphic design or just showing some stuff with it
ἔρως
ἔρως4mo ago
not really, im awful at it and have very little interest in it
FF
FFOP4mo ago
the graphics you made was good on that one you send me
ἔρως
ἔρως4mo ago
its just squares and rectangles with the automatic align tool nothing special
FF
FFOP4mo ago
i know excali has built in tools for that but you can use it on blogs if you have one
ἔρως
ἔρως4mo ago
i dont have one
FF
FFOP4mo ago
nvm then
ἔρως
ἔρως4mo ago
but i see lots of diagrams on blogs and stuff
FF
FFOP4mo ago
@ἔρως i think i understand but i will read more
ἔρως
ἔρως4mo ago
alright do you understand why the js now isnt doing what you expect it to do?
Melodium
Melodium4mo ago
please send your code in codeblocks, not inline code
FF
FFOP4mo ago
sorry my bad i will fix it when i have time
Melodium
Melodium4mo ago
👍
FF
FFOP4mo ago
yes i did research about shallow copy and more importantly about pass by value and pass by reference terms Javascript is a pass by value language so, when i pass an array as an argument it holds a reference VALUE In my 2D array, forEach go over arrays. So, arr parameter holds a reference to that nested array. If i want to change it with its index like arr[index], i can do it because the variables inside that array empty strings which is primitive type but if i want to change the arr itself which holds a reference as a VALUE, i lost that reference. But if Javascript would be a pass by reference language my statement would be true
ἔρως
ἔρως4mo ago
yeah, if it was an actual pointer, yes like in c but it's not like it
FF
FFOP4mo ago
Yes, primivite values have pointer too but JS handles it for us. I will remove the pointer thing from my answer. True is just "reference"
ἔρως
ἔρως4mo ago
yes, reference is better
FF
FFOP4mo ago
How are you my friend
ἔρως
ἔρως4mo ago
im okay
FF
FFOP4mo ago
nice of you
Want results from more Discord servers?
Add your server