I have the following simple code, working with Java Array
var fruits = [["Banana", "Orange", "Apple", "Mango"]];
var names = ["Adam", "Emma", "Joe", "David"];
var newArray=[];
for (var i = 0 ; i < 4 ; i++){
newArray[i] = fruits[0]; // Copy fruits[] into newArray[]
newArray[i][1] = names[i]; // Then replace the 2nd element with names[]
}
The desire outcome is this...
newArray[0] = ["Banana", "Adam" , "Apple", "Mango"]
newArray[1] = ["Banana", "Emma" , "Apple", "Mango"]
newArray[2] = ["Banana", "Joe" , "Apple", "Mango"]
newArray[3] = ["Banana", "David", "Apple", "Mango"]
However I get this final result and can't work out why...
newArray[0] = ["Banana", "David" , "Apple", "Mango"]
newArray[1] = ["Banana", "David" , "Apple", "Mango"]
newArray[2] = ["Banana", "David" , "Apple", "Mango"]
newArray[3] = ["Banana", "David" , "Apple", "Mango"]
I'm only very new to JS so figure this could be down to something simple but at stage it's a brick wall that can't be pass. Your help would be greatly appreciated.
-
1Java is not JavaScript - it's important to be clear about the distinction.zfrisch– zfrisch2018年11月26日 00:19:59 +00:00Commented Nov 26, 2018 at 0:19
1 Answer 1
The problem is:
newArray[i] = fruits[0]; // Copy fruits[] into newArray[]
newArray[i] is not a copy of the first item in fruits - rather, it's just another reference to the same object in memory. So, when you change newArray[i], you also change fruits[0], and you also change any other variables which hold the same reference to fruits[0] - that is, every item in newArray.
Explicitly clone fruits[0] on each iteration instead:
var fruits = [
["Banana", "Orange", "Apple", "Mango"]
];
var names = ["Adam", "Emma", "Joe", "David"];
var newArray = [];
for (var i = 0; i < 4; i++) {
newArray[i] = [...fruits[0]];
newArray[i][1] = names[i];
}
console.log(newArray);
[...fruits[0]] is spread syntax - it creates a shallow copy of fruits[0].
You might consider using .map instead though, .map is a bit more appropriate when you're creating a new array from every element of another:
var fruits = [
["Banana", "Orange", "Apple", "Mango"]
];
var names = ["Adam", "Emma", "Joe", "David"];
const newArray = names.map((name) => {
const arr = [...fruits[0]];
arr[1] = name;
return arr;
});
console.log(newArray);
Alternatively, without spread, use slice:
var fruits = [
["Banana", "Orange", "Apple", "Mango"]
];
var names = ["Adam", "Emma", "Joe", "David"];
const newArray = names.map((name) => {
const arr = fruits[0].slice();
arr[1] = name;
return arr;
});
console.log(newArray);
3 Comments
slice instead of spread syntax, see edit (or you can use Babel to transpile down to ES5 automatically, allowing you to write in the latest and greatest version of the language, it's great with larger projects)