I have a loop that switches values at every iteration, and I need the result of that operation to be pushed into the arr array so when I return it the result should be [ [ 'b', 'a', 'c' ], [ 'b', 'c', 'a' ] ] but instead it’s returning [ [ 'b', 'c', 'a' ], [ 'b', 'c', 'a' ] ] even though when I console log arg within the loop it returns the expected result. What gives?
function test(arg) {
let arr = []
for (let i = 0; i < 2; i++) {
let savedValue = arg[i]
arg[i] = arg[i + 1]
arg[i + 1] = savedValue
console.log(arg)
arr.push(arg)
}
return arr
}
console.log(test(['a', 'b', 'c']))
let a = [1, 3, 4]
let b = a
b[0] = 100
console.log(a) // [100, 3, 4]
When you assign or pass an array as an argument you don’t make a copy of the array, you pass a reference to the existing instance. So you’re changing in your example the same array and push the reference to the same array in the resulting array.
I know how to make a copy. Can you show me how to achieve what I’m looking for? It’s still returning [ [ 'b', 'c', 'a' ], [ 'b', 'c', 'a' ] ] when I iterate over the copy.
With all due respect this is not productive at all and doesn’t achieve anything other than a waste of time on something that can be explained in one post. You don’t even need to explain as I will observe the code and make my conclusions about it, and thus I would have learned something new without going back and forth on something so simple.
You learn far less than you expect from reading somebody else’s code. It is a tempting trap, but reading somebody else’s code is a different (important but different) skill from writing and debugging code.
I disagree. The epiphanies that you experience after understanding somebody’s else’s code stick with you also, allowing you to reproduce it in other contexts, that has always been the case in my learning. So if someone is asking for a straightforward answer then that also should be respected.
I understand why it is tempting to think that, but it just is two different sets of skills. Both sets are important, but we focus on writing and debugging here, not reading other people’s code. You might be different, but I have not seen effective learning by reading and coping other people’s code from other learners in the last decade.
In any case, there is a strict ‘no providing solutions’ rule, and repeatedly asking someone to do something that they say they do not want to do or will not do just is not ok.
I was not aware of that rule, apologies. Now, I moved the copied array into the loop but it’s still not giving me quite the result I’m looking for. I just don’t understand why my original code doesn’t work. I’m telling the loop to perform 2 operations so that ['a', 'b', 'c'] becomes [ 'b', 'a', 'c' ] at which point the array should be pushed into arr. Then repeat that whole operation on [ 'b', 'a', 'c' ] at the next index. When I console log it I see the expected result and in my previous experiences the values being pushed out of the loop were always the same being console logged. So what is different now? The changes I made return a different result.
function test(arg) {
let arr = []
for (let i = 0; i < 2; i++) {
let copy = [...arg]
let savedValue = copy[i]
copy[i] = copy[i + 1]
copy[i + 1] = savedValue
console.log(copy)
arr.push(copy)
}
return arr
}
let someNumber = 5;
let thisBoolean = true;
let thatString = "foo";
But arrays and objects are useful things. But they contain lots of values, and a Javascript variable can only hold one value, so the Javascript engine has to be clever.
const firstArray = [1, 2, 3];
const secondArray = firstArray;
firstArray[0] = 42;
console.log(secondArray); // both were changed
Javascript holds the more complex object somewhere in memory and the variable holds just the location in memory to go find the values of the complex object. Copying the variable around just repeats the reference to the same place in memory.
This line pushes a reference to arg, which is an array.
But these lines keep changing the contents of that location in your computer’s memory.
In the end, you have something that looks like
// all the same location in memory
arr = [
go_look_at_memory_location_0x7f36cf570100,
go_look_at_memory_location_0x7f36cf570100,
go_look_at_memory_location_0x7f36cf570100,
go_look_at_memory_location_0x7f36cf570100,
go_look_at_memory_location_0x7f36cf570100,
]
while with the change to make a shallow copy of arg with the spread syntax you end up with something like
// look at the last digits
arr = [
go_look_at_memory_location_0x7f36cf570100,
go_look_at_memory_location_0x7f36cf570104,
go_look_at_memory_location_0x7f36cf570108,
go_look_at_memory_location_0x7f36cf57010c,
go_look_at_memory_location_0x7f36cf570110,
]