Changing one value in 2D array changes whole line - javascript

Ok so in doing a simple game of life simulation I came across this really wierd problem I have a 2D array and Im trying to change one value at cords x,y simple right?
let arr = new Array(10).fill(new Array(10).fill(1))
arr[1][1] = 0
console.log(arr[3])
I've done this in the past in multiple projects but now for some strange reason now it changes all arr[x][1] instead of just arr[1][1]

new Array creates an object (almost everything in JS is object) that is used later to fill another array with THE SAME array (object, in fact) 10 times. So, what you are doing by arr[1][1] = 0; is changing object's property that gets reflected everywhere.
To prove that it is the same object everywhere in the array, try to check like arr[4] === arr[7] it will give you true.

new Array(10).fill(1) generate a reference which is being used in each slot of array. So, modifying an index of any array also update others array, as they have the same reference.
let arr = new Array(10).fill(new Array(10).fill(1))
You need to create a new reference of array for each index. You can use array#from to generate it.
const arr = Array.from({length: 10}, _ => new Array(10).fill(1));
arr[1][1] = 0
console.log(arr)

Array#fill by definition fills up the array with the same object.
You should do this:
new Array(10).fill(0).map(() => new Array(10).fill(1)));

Related

Why push does not working with set methond in Map object

So very quick question here which I wasn't able to get sorted when searching google.
I have some code that works which has a Map object this.tweet and a (key,value) of (string,array). I push a value into the array and re-set Map object.
const newTweet = this.tweet.get(tweetName) || [];
newTweet.push(time);
this.tweet.set(tweetName, newTweet);
However, I am a minimalist freak and want a one-liner. When I want to add something to the array, I was wondering why I am not able to do this
this.tweet.set(tweetName, newTweet.push(time));
I keep getting a newTweet.push(time) is not a function error.
Thanks
Look at some documentation for push
The push() method adds one or more elements to the end of an array and returns the new length of the array.
Since you want to pass the array to set you can't use the return value of push.
You could create a completely new array instead:
const newTweet = this.tweet.get(tweetName) || [];
this.tweet.set(tweetName, [...newTweet, time]);

Blank Array Returned A Length of 5

I have been watching PluralSight's Rapid JavaScript Training by Mark Zamoyta and I came across this. He showed these two examples. I've been trying to wrap my head around it, but still could not understand.
How is it able to capture the length of the entries after the array was created using new Array() method, seeing that it returned a blank array []. If it's blank like this [], shouldn't it return -1?
var entries = [1,2,3,4,5];
entries.length
=> 5
entries
=> [ 1, 2, 3, 4, 5 ]
var entries = new Array(5);
entries.length
=> 5
entries
=> []
var myArray = new Array(5);
When you define an array by passing the constructor an integer like above, memory is allocated for 5 slots in the array. If you examine the array, you will find:
console.log(myArray[1]);
=> undefined
console.log(myArray.toString);
=> ,,,,
As you can see, there are indeed five elements in the array, each of them undefined. So your array isn't "blank."
It is probably bad practice to initialize an array in this manner, as there just isn't a good use case for it. Pushing to the array will yield:
myArray.push("value");
console.log(myArray.toString);
=> ,,,,,value
...which is never what you want. I would advise initializing the array like below and forget that passing an integer to the constructor is even an option:
var myArray = [];
The length property of an array in JS is not calculated on the fly - it can also be set manually via the constructor or an assignment, and it's updated as objects are added or removed (Spec):
Specifically, whenever a property is added whose name is an array index, the length property is changed, if necessary, to be one more than the numeric value of that array index[.]
It's a plain property that's kept up-to-date, not a calculation. Using the constructor new Array(5) initializes an array with length set to 5. You can also set it manually, which fills in undefined or truncates the array as needed:
var arr = [];
arr.length = 3;
// arr is now [undefined, undefined, undefined]

what new Array(20) actually do

Here i have a Store constructor which has a property named arr which is created using new Array(height*width) provided height and length were sent as arguments to Store constructor.What i know is new Array(20) will create an array which can contain 20 elements.
The Store constructor has a prototype property which uses a map array and fill this.arr of the new Store instance.
But surprisingly the array length gets extended after the fill up process.It becomes 40.I know push method insert elements at the end of an array.Does it mean the array was already has 20 elements.But it supposed to be empty ,right?? i am confused!!!
var map=['d d d d d ',
'e e e e e ']
function Store(width,height){
this.width=width;
this.height=height;
this.arr=new Array(this.width*this.height);
}
Store.prototype.set=function(map){
for(i=0;i<this.height;i++){
for(j=0;j<this.width;j++){
this.arr.push(map[i][j]);
}
}
}
var store=new Store(map[0].length,map.length);
document.write('previously : '+store.arr.length+'</br>');
store.set(map);
document.write('now : '+store.arr.length);
When you create an Array, with Array constructor, it creates a sparse Array with the length specified. So when you say Array(20) it has created an Array with 20 elements (by changing the length property), which are not defined yet, in it. So, lets say that the length is set to 5 and you are trying to access the element at 0. Now, JavaScript will look for the property 0 in the Array object and it will not find anything. So, it will return undefined. But when you do something like array[0] = 1, it assigns the property 0, the value 1. So the next time when you look for array[0], it will return 1. Practically, when you simply create an Array, there is nothing in it.
Regarding the push, quoting from MDN's Array.prototype.push,
The push() method adds one or more elements to the end of an array and returns the new length of the array.
So, it has been extending the array whenever you are pushing something to it. You might want to do something like this
this.arr[i][j] = map[i][j];
new Array(20) creates an array with 20 elements that are undefined. But the very storage within the array is preallocated. This is considered to be a more efficient way of handling arrays. If you know the array length in advance, always use this approach. (By the way, it is even more beneficial to have all the elements of the array to be of the same type)
In case you preallocate an array, do not push elements to it. Assign values to elements within the array, like this:
var map=['d d d d d ',
'e e e e e ']
function Store(width,height){
this.width=width;
this.height=height;
this.arr=new Array(this.width*this.height);
}
Store.prototype.set=function(map){
for(i=0;i<this.height;i++){
for(j=0;j<this.width;j++){
this.arr[i*j+j] = map[i][j];
}
}
}
var store=new Store(map[0].length,map.length);
document.write('previously : '+store.arr.length+'</br>');
store.set(map);
document.write('now : '+store.arr.length);
If you do not know the array size in advance, create an empty zero length array, and push (or unshift, push puts an element to the last position in the array, unshift puts the element to the first, 0 index, position in the array) elements to it. This works slower, because each push or unshift will dynamically change the size of the array.

Javascript array best practice to use [] instead of new array?

I read at many tutorials that the current best practices to create a new javascript array is to use
var arr = []
instead of
var arr = new Array()
What's the reasoning behind that?
It might be because the Array object can be overwritten in JavaScript but the array literal notation cannot. See this answer for an example
Also note that doing:
var x = [5];
Is different than doing:
var x = new Array(5);
The former creates an initializes an array with one element with value of 5. The later creates an initializes an array with 5 undefined elements.
It's less typing, which in my book always wins :-)
Once I fixed a weird bug on one of our pages. The page wanted to create a list of numeric database keys as a Javascript array. The keys were always large integers (a high bit was always set as an indicator). The original code looked like:
var ids = new Array(${the.list});
Well, guess what happened when the list had only one value in it?
var ids = new Array(200010123);
which means, "create an array and initialize it so that there are 200 million empty entries".
Usually an array literal(var a=[1,2,3] or a=[]) is the way to go.
But once in a while you need an array where the length itself is the defining feature of the array.
var A=Array(n) would (using a literal) need two expressions-
var A=[]; A.length=n;
In any event, you do not need the 'new' operator with the Array constructor,
not in the way that you DO need 'new' with a new Date object, say.
To create Array without Length
var arr = [];
To create Array with Length more dynamically
var arr;
( arr = [] ).length = 10; // 10 is array length
To create Array with Length less dynamically
var arr = [];
arr.length = 10;

What’s the difference between "Array()" and "[]" while declaring a JavaScript array?

What's the real difference between declaring an array like this:
var myArray = new Array();
and
var myArray = [];
There is a difference, but there is no difference in that example.
Using the more verbose method: new Array() does have one extra option in the parameters: if you pass a number to the constructor, you will get an array of that length:
x = new Array(5);
alert(x.length); // 5
To illustrate the different ways to create an array:
var a = [], // these are the same
b = new Array(), // a and b are arrays with length 0
c = ['foo', 'bar'], // these are the same
d = new Array('foo', 'bar'), // c and d are arrays with 2 strings
// these are different:
e = [3] // e.length == 1, e[0] == 3
f = new Array(3), // f.length == 3, f[0] == undefined
;
Another difference is that when using new Array() you're able to set the size of the array, which affects the stack size. This can be useful if you're getting stack overflows (Performance of Array.push vs Array.unshift) which is what happens when the size of the array exceeds the size of the stack, and it has to be re-created. So there can actually, depending on the use case, be a performance increase when using new Array() because you can prevent the overflow from happening.
As pointed out in this answer, new Array(5) will not actually add five undefined items to the array. It simply adds space for five items. Be aware that using Array this way makes it difficult to rely on array.length for calculations.
The difference between creating an array with the implicit array and the array constructor is subtle but important.
When you create an array using
var a = [];
You're telling the interpreter to create a new runtime array. No extra processing necessary at all. Done.
If you use:
var a = new Array();
You're telling the interpreter, I want to call the constructor "Array" and generate an object. It then looks up through your execution context to find the constructor to call, and calls it, creating your array.
You may think "Well, this doesn't matter at all. They're the same!". Unfortunately you can't guarantee that.
Take the following example:
function Array() {
this.is = 'SPARTA';
}
var a = new Array();
var b = [];
alert(a.is); // => 'SPARTA'
alert(b.is); // => undefined
a.push('Woa'); // => TypeError: a.push is not a function
b.push('Woa'); // => 1 (OK)
In the above example, the first call will alert 'SPARTA' as you'd expect. The second will not. You will end up seeing undefined. You'll also note that b contains all of the native Array object functions such as push, where the other does not.
While you may expect this to happen, it just illustrates the fact that [] is not the same as new Array().
It's probably best to just use [] if you know you just want an array. I also do not suggest going around and redefining Array...
There is an important difference that no answer has mentioned yet.
From this:
new Array(2).length // 2
new Array(2)[0] === undefined // true
new Array(2)[1] === undefined // true
You might think the new Array(2) is equivalent to [undefined, undefined], but it's NOT!
Let's try with map():
[undefined, undefined].map(e => 1) // [1, 1]
new Array(2).map(e => 1) // "(2) [undefined × 2]" in Chrome
See? The semantics are totally different! So why is that?
According to ES6 Spec 22.1.1.2, the job of Array(len) is just creating a new array whose property length is set to the argument len and that's it, meaning there isn't any real element inside this newly created array.
Function map(), according to spec 22.1.3.15 would firstly check HasProperty then call the callback, but it turns out that:
new Array(2).hasOwnProperty(0) // false
[undefined, undefined].hasOwnProperty(0) // true
And that's why you can not expect any iterating functions working as usual on arrays created from new Array(len).
BTW, Safari and Firefox have a much better "printing" to this situation:
// Safari
new Array(2) // [](2)
new Array(2).map(e => 1) // [](2)
[undefined, undefined] // [undefined, undefined] (2)
// Firefox
new Array(2) // Array [ <2 empty slots> ]
new Array(2).map(e => 1) // Array [ <2 empty slots> ]
[undefined, undefined] // Array [ undefined, undefined ]
I have already submitted an issue to Chromium and ask them to fix this confusing printing:
https://bugs.chromium.org/p/chromium/issues/detail?id=732021
UPDATE: It's already fixed. Chrome now printed as:
new Array(2) // (2) [empty × 2]
Oddly enough, new Array(size) is almost 2x faster than [] in Chrome, and about the same in FF and IE (measured by creating and filling an array). It only matters if you know the approximate size of the array. If you add more items than the length you've given, the performance boost is lost.
More accurately: Array( is a fast constant time operation that allocates no memory, wheras [] is a linear time operation that sets type and value.
For more information, the following page describes why you never need to use new Array()
You never need to use new Object() in
JavaScript. Use the object literal {}
instead. Similarly, don’t use new Array(),
use the array literal []
instead. Arrays in JavaScript work
nothing like the arrays in Java, and
use of the Java-like syntax will
confuse you.
Do not use new Number, new String, or
new Boolean. These forms produce
unnecessary object wrappers. Just use
simple literals instead.
Also check out the comments - the new Array(length) form does not serve any useful purpose (at least in today's implementations of JavaScript).
In order to better understand [] and new Array():
> []
[]
> new Array()
[]
> [] == []
false
> [] === []
false
> new Array() == new Array()
false
> new Array() === new Array()
false
> typeof ([])
"object"
> typeof (new Array())
"object"
> [] === new Array()
false
> [] == new Array()
false
The above result is from Google Chrome console on Windows 7.
The first one is the default object constructor call. You can use it's parameters if you want.
var array = new Array(5); //initialize with default length 5
The second one gives you the ability to create not empty array:
var array = [1, 2, 3]; // this array will contain numbers 1, 2, 3.
I can explain in a more specific way starting with this example that's based on Fredrik's good one.
var test1 = [];
test1.push("value");
test1.push("value2");
var test2 = new Array();
test2.push("value");
test2.push("value2");
alert(test1);
alert(test2);
alert(test1 == test2);
alert(test1.value == test2.value);
I just added another value to the arrays, and made four alerts:
The first and second are to give us the value stored in each array, to be sure about the values. They will return the same!
Now try the third one, it returns false, that's because
JS treats test1 as a VARIABLE with a data type of array, and it treats test2 as an OBJECT with the functionality of an array, and
there are few slight differences here.
The first difference is when we call test1 it calls a variable without thinking, it just returns the values that are stored in this variable disregarding its data type!
But, when we call test2 it calls the Array() function and then it stores our "Pushed" values in its "Value" property, and the same happens when we alert test2, it returns the "Value" property of the array object.
So when we check if test1 equals test2 of course they will never return true, one is a function and the other is a variable (with a type of array), even if they have the same value!
To be sure about that, try the 4th alert, with the .value added to it; it will return true. In this case we tell JS "Disregarding the type of the container, whether was it function or variable, please compare the values that are stored in each container and tell us what you've seen!" that's exactly what happens.
I hope I said the idea behind that clearly, and sorry for my bad English.
There is no difference when you initialise array without any length. So var a = [] & var b = new Array() is same.
But if you initialise array with length like var b = new Array(1);, it will set array object's length to 1. So its equivalent to var b = []; b.length=1;.
This will be problematic whenever you do array_object.push, it add item after last element & increase length.
var b = new Array(1);
b.push("hello world");
console.log(b.length); // print 2
vs
var v = [];
a.push("hello world");
console.log(b.length); // print 1
There's more to this than meets the eye. Most other answers are correct BUT ALSO..
new Array(n)
Allows engine to reallocates space for n elements
Optimized for array creation
Created array is marked sparse which has the least performant array operations, that's because each index access has to check bounds, see if value exists and walk the prototype chain
If array is marked as sparse, there's no way back (at least in V8), it'll always be slower during its lifetime, even if you fill it up with content (packed array) 1ms or 2 hours later, doesn't matter
[1, 2, 3] || []
Created array is marked packed (unless you use delete or [1,,3] syntax)
Optimized for array operations (for .., forEach, map, etc)
Engine needs to reallocate space as the array grows
This probably isn't the case for older browser versions/browsers.
The first one is the default object constructor call.mostly used for dynamic values.
var array = new Array(length); //initialize with default length
the second array is used when creating static values
var array = [red, green, blue, yellow, white]; // this array will contain values.
The difference of using
var arr = new Array(size);
Or
arr = [];
arr.length = size;
As been discussed enough in this question.
I would like to add the speed issue - the current fastest way, on google chrome is the second one.
But pay attention, these things tend to change a lot with updates. Also the run time will differ between different browsers.
For example - the 2nd option that i mentioned, runs at 2 million [ops/second] on chrome, but if you'd try it on mozilla dev. you'd get a surprisingly higher rate of 23 million.
Anyway, I'd suggest you check it out, every once in a while, on different browsers (and machines), using site as such
As I know the diference u can find the slice(or the other funcitons of Array) like code1.and code2 show u Array and his instances:
code1:
[].slice; // find slice here
var arr = new Array();
arr.slice // find slice here
Array.prototype.slice // find slice here
code2:
[].__proto__ == Array.prototype; // true
var arr = new Array();
arr.__proto__ == Array.prototype; // true
conclusion:
as u can see [] and new Array() create a new instance of Array.And they all get the prototype functions from Array.prototype
They are just different instance of Array.so this explain why
[] != []
:)
There is no big difference, they basically do the same thing but doing them in different ways, but read on, look at this statement at W3C:
var cars = ["Saab", "Volvo","BMW"];
and
var cars = new Array("Saab", "Volvo", "BMW");
The two examples above do exactly the same. There is no need to use
new Array(). For simplicity, readability and execution speed, use the
first one (the array literal method).
But at the same time, creating new array using new Array syntax considered as a bad practice:
Avoid new Array()
There is no need to use the JavaScript's built-in array constructor
new Array().
Use [] instead.
These two different statements both create a new empty array named
points:
var points = new Array(); // Bad
var points = []; // Good
These two different statements both create a new array containing 6
numbers:
var points = new Array(40, 100, 1, 5, 25, 10); // Bad
var points = [40, 100, 1, 5, 25, 10]; // Good
The new keyword only complicates the code. It can also produce some
unexpected results:
var points = new Array(40, 100); // Creates an array with two elements (40 and 100)
What if I remove one of the elements?
var points = new Array(40); // Creates an array with 40 undefined elements !!!!!
So basically not considered as the best practice, also there is one minor difference there, you can pass length to new Array(length) like this, which also not a recommended way.
I've incurred in a weird behaviour using [].
We have Model "classes" with fields initialised to some value. E.g.:
require([
"dojo/_base/declare",
"dijit/_WidgetBase",
], function(declare, parser, ready, _WidgetBase){
declare("MyWidget", [_WidgetBase], {
field1: [],
field2: "",
function1: function(),
function2: function()
});
});
I found that when the fields are initialised with [] then it would be shared by all Model objects. Making changes to one affects all others.
This doesn't happen initialising them with new Array(). Same for the initialisation of Objects ({} vs new Object())
TBH I am not sure if its a problem with the framework we were using (Dojo)
Well, var x = new Array() is different than var x = [] is different in some features I'll just explain the most useful two (in my opinion) of them.
Before I get into expalining the differences, I will set a base first; when we use x = [] defines a new variable with data type of Array, and it inherits all the methods that belong to the array prototype, something pretty similar (but not exactly) to extending a class. However, when we use x = new Array() it initilizes a clone of the array prototype assigned to the variable x.
Now let's see what are the difference
The First Difference is that using new Array(x) where x is an integer, initilizes an array of x undefined values, for example new Array(16) will initialize an array with 16 items all of them are undefined. This is very useful when you asynchronously fill an array of a predefined length.
For example (again :) ) let's say you are getting the results of 100 competitiors, and you're receiving them asynchronously from a remote system or db, then you'll need to allocate them in the array according to the rank once you receive each result. In this very rare case you will do something like myArray[result.rank - 1] = result.name, so the rank 1 will be set to the index 0 and so on.
The second difference is that using new Array() as you already know, instanciates a whole new clone of the array prototype and assigns it to your variable, that allows you to do some magic (not recommended btw). This magic is that you can overwrite a specific method of the legacy array methods. So, for example you can set the Array.push method to push the new value to the beginning of the array instead of the end, and you can also add new methods (this is better) to this specific clone of the Array Prototype. That will allow you to define more complex types of arrays throughout your project with your own added methods and use it as a class.
Last thing, if you're from the very few people (that I truly love) that care about processing overhead and memory consumption of your app, you'd never tough new Array() without being desperate to use it :).
I hope that has explained enough about the beast new Array() :)
I found a difference while using promises. While using array of promises (say arr, initialised as arr=[]), got an error in Promise.all(arr). Whereas when declared as arr = Array(), did not get compilation issues. Hope this helps.
I've found one difference between the two constructions that bit me pretty hard.
Let's say I have:
function MyClass(){
this.property1=[];
this.property2=new Array();
};
var MyObject1=new MyClass();
var MyObject2=new MyClass();
In real life, if I do this:
MyObject1.property1.push('a');
MyObject1.property2.push('b');
MyObject2.property1.push('c');
MyObject2.property2.push('d');
What I end up with is this:
MyObject1.property1=['a','c']
MyObject1.property2=['b']
MyObject2.property1=['a','c']
MyObject2.property2=['d']
I don't know what the language specification says is supposed to happen, but if I want my two objects to have unique property arrays in my objects, I have to use new Array().
Using the Array constructor makes a new array of the desired length and populates each of the indices with undefined, the assigned an array to a variable one creates the indices that you give it info for.

Categories