JavaScript matrix wired behaviour when using new Array() [duplicate] - javascript

This question already has answers here:
Array.fill(Array) creates copies by references not by value [duplicate]
(3 answers)
Closed 4 years ago.
When i use Array.fill to fill a multidimensional array, i get a weird behaviour when pushing to one of the arrays:
var arr = Array(2).fill([]);
arr[0].push(5);
console.log(arr);
//=> prints [[5], [5]]

fill is essentially doing this:
var content = [];
for (var i = 0; i < 2; i += 1) {
arr[i] = content;
}
So, your array will have a reference to the array you've passed to fill in each property.

It sounds weird, but what your code actually does is create an array ([]) and put a reference for that array in each of the items of the Array(2). So whenever you change that reference - every array that is referenced to that Array is changed.
It's exactly the same as:
var a = [];
var arr = Array(2).fill(a);
a.push(5);
console.log(arr[0][0], arr[1][0]);
a[0] = 2;
console.log(arr[0][0], arr[1][0]);
You can see that the values inside the arr are affected by the change to the a array.

Related

Javascript Grammer: how to assign correct values to an array of objects [duplicate]

This question already has answers here:
new Array(_).fill(object) does not create new instances of object [duplicate]
(5 answers)
Array.prototype.fill() with object passes reference and not new instance
(7 answers)
Closed 2 years ago.
let's look at the code:
Test() {
let array1 = new Array(5).fill({ a: 0 })
let array2 = new Array(5).fill({ a: 0 })
for (let i = 0; i < 5; i++) {
setTimeout(() => {
array1[i].a = i
array2[i] = {a:i}
console.warn("array = ", array1)
console.warn("array2 = ", array2)
}, 0.2 * i)
}
}
In this case, I wanna assign a series of values to the array1 & array2, and there are two ways to do it, which lead to totally different results.
In the case array1[i].a = i, after all the code is ran, the result is array = [{a:4},{a:4},{a:4},{a:4},{a:4}], which is not what i wanted.
In the second case array2[i] = {a:i}, the result will be [{a:0},{a:1},{a:2},{a:3},{a:4}] as expected.
I wanna know why is it like this? What's the machanics behind this phenomenon?
Thank you.
When you call .fill() and pass an object, you assign the exact same object to every element of the array. Thus, modifying a property at one array index modifies the same property at all the other indexes, because they're all pointing to the same thing.
There are a variety of ways around this issue. You could fill the array with 0 or null or some dummy value and then iterate through with .forEach(), or more simply just use an indexed for loop to initialize each element. If you initialize with { a: 0} in a for loop, a new object will be created on each iteration.

Array value assignment not working as expected Javascript [duplicate]

This question already has answers here:
Array.fill(Array) creates copies by references not by value [duplicate]
(3 answers)
Closed 2 years ago.
The code I'm working on right now requires me to assign a value to a single cell in a 2-D array.
But the assignment doesn't seem to work out as expected.
let b = new Array(3).fill(new Array(3).fill(0));
b[1][1] = 1;
console.log(b.toString());
I just can't really understand why it produces this output.
The below code gives me the output I expect but I would really prefer being able to do it in a manner that resembles the first snippet.
let b = []
for(let i = 0; i < 3; i++){
b.push([])
for(let j = 0; j < 3; j++){
b[i].push(0)
}
}
b[1][1] = 1
console.log(b.toString())
You can avoid assigning the same array reference by using the built in mapping callback of Array.from()
let b = Array.from({length:3}, (_,i) => Array(3).fill(i));
console.log(b)
In your first example, it creates one array, then fills every element to that one array. This means that a change in one will be reflected in everything else. If you want to construct a new array for each element, then you could try mapping it:
let b = new Array(3).fill(null).map(_ => new Array(3).fill(0));
b[1][1] = 1;
console.log(b.toString());

Javascript push and loop [duplicate]

This question already has answers here:
Create an array with same element repeated multiple times
(25 answers)
Closed 2 years ago.
I currently have this array: var arr = []
How do I push multiple "hello" strings into the array using a for loop?
I tried
var newArray = arr.push("hello")10;
try new Array forEach or simple for-loop should work.
var arr = [];
// method 1
new Array(5).fill(0).forEach(() => arr.push("hello"));
// alternate method
for (let i = 0; i < 5; i++) {
arr.push("world");
}
console.log(arr);
// Updating based on suggesion #mplungjan, quick way without loop.
var arr2 = Array(10).fill("hello");
console.log(arr2)

Weird behaviour in Array.fill [duplicate]

This question already has answers here:
Array.fill(Array) creates copies by references not by value [duplicate]
(3 answers)
Closed 4 years ago.
When i use Array.fill to fill a multidimensional array, i get a weird behaviour when pushing to one of the arrays:
var arr = Array(2).fill([]);
arr[0].push(5);
console.log(arr);
//=> prints [[5], [5]]
fill is essentially doing this:
var content = [];
for (var i = 0; i < 2; i += 1) {
arr[i] = content;
}
So, your array will have a reference to the array you've passed to fill in each property.
It sounds weird, but what your code actually does is create an array ([]) and put a reference for that array in each of the items of the Array(2). So whenever you change that reference - every array that is referenced to that Array is changed.
It's exactly the same as:
var a = [];
var arr = Array(2).fill(a);
a.push(5);
console.log(arr[0][0], arr[1][0]);
a[0] = 2;
console.log(arr[0][0], arr[1][0]);
You can see that the values inside the arr are affected by the change to the a array.

Dynamically create js Array filled with certain value [duplicate]

This question already has answers here:
Create an array with same element repeated multiple times
(25 answers)
Closed 7 years ago.
I'm wondering if there is a way to create javascript/jquery array in one-liner to receive something like:
my_array = ['-', '-', ,'-' ,'-']
Idea is that array should be created with dynamic length and all values filled with given value.
Thanks in advance!
Try:
var total = 4;
var my_array = new Array(total + 1).join("-").split("");
document.write(JSON.stringify(my_array))
.fill Support The native function will be added in (ECMAScript 6), but for now is not available.
if(!Array.prototype.fill){
Array.prototype.fill = function(val){
for (var i = 0; i < this.length; i++){
this[i] = val
}
return this
}
}
var my_array = new Array(4).fill("-"); //returns ["-","-","-","-"]
Try to use:
Array.apply(null, new Array(63)).map(String.prototype.valueOf,"-")

Categories

Resources