This question already has answers here:
Most efficient way to create a zero filled JavaScript array?
(45 answers)
How to initialize an array's length in JavaScript?
(20 answers)
Closed 8 years ago.
How to create an array with length 3 and the value for the array element is 0.
if i give the length of the array as 3, then the array should be like below
a[0]=0;
a[1]=0;
a[2]=0;
I have tried this new Array(3), it creates an array a[,,,] of length 3 and new Array(0,0,0) creates an array a[0,1,2], Is it possible to create an array by defining the length and value for the array element?
Thanks in Advance
Is it possible to create an array by defining the length and value for the array element?
If you mean, some kind of pre-initializing constructor or fill operation, no, JavaScript doesn't have that.
If you know you want three elements as of when you're writing the code, you can do this:
a = [0, 0, 0];
It's called an array initializer.
If you don't know in advance (e.g., when writing the code) how big the array should be, you can just fill it as necessary:
a = [];
var index;
for (index = 0; index < initialSize; ++index) {
a[index] = 0;
}
Note that you don't have to pre-allocate room in the array; the array can "grow" as required. (This may seem strange, but standard JavaScript arrays aren't really arrays at all, although JavaScript engines will frequently try to use true arrays as an optimization if they think they can.)
But if you want to, you can tell the engine engine in advance what length you want, by using:
a = new Array(initialSize);
...rather than a = []; above. (More on this near the end.)
If you wanted to, you could add a function to the Array function object to do that:
Array.createFilled(length, value) {
var a = new Array(length); // Or of course, `var a = [];`
var i;
for (i = 0; i < length; ++i) {
a[i] = value;
}
return a;
}
Then using it in the various places you want a pre-filled array:
var a = Array.createFilled(3, 0); // 0,0,0
Side note: Always be sure to declare your variables, e.g., have a var a; somewhere prior to the line above.
Obviously, telling the engine in advance how big the array should be would let it do better optimization, right? Not necessarily! It may help some engines (a small bit), hinder others (a small bit), and/or make no difference:
Related
This question already has answers here:
Subclassing Javascript Arrays. TypeError: Array.prototype.toString is not generic
(7 answers)
Closed 6 years ago.
I'm trying to create an Object/Class in Javascript that behaves like an Array but with some added functionalities.
I've achieved this with these simple lines:
var Newclass = Array
Newclass.prototype.get_by_id = function(){}
However, I'm trying to perform some actions just when I call this new class, so elements I'm adding to this are treated (and transformed, if needed) in a specific way.
I'm wondering if there is a way of making it on the fly, so I could do something like:
var a = New Newclass('hello', 'goodbye', 'good afternoon')
And automatically, get variable a to be (for example):
console.log(a)
["HELLO", "GOODBYE", "GOOD AFTERNOON"]
I know how to do it with loops and Array functions (like map and so), but I'd like to know if there is anyway to overwrite the constructor (on this Newclass) so it gets applied automatically for everyone of its elements on creation, without breaking anything.
EDIT
Thank you everyone for your time and answers. However, I must say this is not a duplicate, as I'm not asking how to work with arguments (or if they exist), but how to work with them on the construction of an Array derivated class, which I find is totally different.
Even knowing the arguments parameter exists, I still don't know how to process these arguments on the constructor of the Array and having still all the native functions of this kind of object.
You can make your own derivative of an Array:
function uppercaseStringArray(){
Array.call(this);
for(var i = 0; i < arguments.length; i++) this.push(arguments[i]);
}
uppercaseStringArray.prototype = Object.create(Array.prototype);
uppercaseStringArray.prototype.push = function(string){
Array.prototype.push.call(this, string.toUpperCase());
}
This works exactly like you expect and it still has all the properties normal arrays have:
function uppercaseStringArray(){
Array.call(this);
for(var i = 0; i < arguments.length; i++) this.push(arguments[i]);
}
uppercaseStringArray.prototype = Object.create(Array.prototype);
uppercaseStringArray.prototype.push = function(string){
Array.prototype.push.call(this, string.toUpperCase());
}
var a = new uppercaseStringArray('tomato', 'apple', 'pear');
console.log(a);
document.write('[' + a.join(', ') + ']');
You could modify the push method to take an unlimited amount of arguments. Please note, however, that this is not a full array, as a[5] = 'thingy' will not modify the length of your array, so be sure to use only methods to add and remove from your array.
This also indentifies itself as both an Array and an uppercaseStringArray using instanceof. And you can add your own methods to the array, like your get_by_id function in its prototype.
This question already has answers here:
How can I create a two dimensional array in JavaScript?
(56 answers)
Closed 9 years ago.
I use no add in libraries so what i'm looking for is a pure JavaScript solution.
This is not a duplicate of the thread offered. I want this thread opened up as the people that locked it didn't completely read what I was looking for. Offering some trivial function to initialize a dense array is NOT what I'm after. Read what I wrote.
I'm looking for a constructor, not some function that operates on an array of a known dimension. I'm looking for something that "just happens" when a multidimensional array is touched, and that something has to be an honest to goodness constructor that runs in the "background"to create the array elements on demand with no effort on the part of the programmer in the "foreground".
Correct me if I'm wrong, but when using a two dimensional array, one must first initialize the second dimension before attempting to use it.
It would be something like:
myArray[123] = [];
myArray[123][456] = 'Hi';
Is there some way to create a constructor to do that extra initialization automatically that wouldn't trash the existing functionality for a 1D array?
Alternatively, is there a way to create a new 2DArray object that will automatically allow one to use both dimensions with no prep work?
When the application has no foreknowledge of what the subscripts can be is when this issue becomes problematic.
See that question: Is there a more concise way to initialize empty multidimensional arrays?
Solution:
function createArray(length) {
var arr = new Array(length || 0),
i = length;
if (arguments.length > 1) {
var args = Array.prototype.slice.call(arguments, 1);
while(i--) arr[i] = createArray.apply(this, args);
}
return arr;
}
Simply call with an argument for the length of each dimension. Usage examples:
var multiArray = createArray(100,100); Gives a 2-dimensional array of size 100x100
This question already has answers here:
How can I create a two dimensional array in JavaScript?
(56 answers)
Closed 8 years ago.
I have declared a two-dimensional array, like so:
a = [[]]
However, when I try to give a second dimension value using a first dimension index other than 0, it doesn't work:
a[1][0] = "foo" //returns error
Is there a better way around this than manually defining every index you need as an array, i.e.:
a[1] = [];
a[2] = [];
a[3] = [];
//et cetera
N-Dimensional arrays do not exist in javascript - you have to just make arrays containing arrays as elements.
You're getting an error because a = [[]]; declares an array with one element, which happens to also be an array. Therefore a[0] is the internal array, but a[1] does not exist because you never declared it. The easiest way to properly declare a "two dimensional array" would be to use a loop:
var outerArray = [];
var numInternalArrays = 5;
for (var i = 0; i < numInternalArrays; i++) {
outerArray[i] = [];
}
If you know how many elements the root array should have you could do something like this:
var arr =
(Math.pow(2,10)-1).toString(2) // Binary string of 1s. Its length being 10
.split('') // Create an array from this string
.map(function(){return [];}); // Map a new empty array to each index
console.log(arr); // [[],[],[],[],[],[],[],[],[],[]]
This accomplishes the same thing:
for(var arr = [], i=10; i--; arr[i]=[]);
No need to declare arr outside of the for-loop since javascript doesn't have block scope, it will be added to the scope in which it is executed.
a = [[]]
This is an Array, with the first item being an array. Which is why indexing into the first item still works (a[0][0]).
If you want to access the second item as an array, you need to create your array as
a = [[],[]]
See this question for examples of
How can I create a two dimensional array in JavaScript?
If I understand correctly, use a loop:
for (var i = y; i--; a[i] = []);
There are no multidimensional arrays in javascript.
What you are doing is an array of arrays, but the outermost array has only one element (i.e. element 0) whose value is another array. So a[1] (or more generally a[1][x]) is invalid since the outermost array has only one element.
So you can do a[0][x] = "foo" but not the other way around.
So you can either initialize the array with a for loop or do something like var a =[[][][][][]];
You can have the array of arrays start as in:
var a = []; // start with the column array
Then when you want to put something in location [i][j] we can call 'i' the row-index and 'j' the column-index.
if (!a[i]) { // check for row existing
a[i] = []; // .. and create it if not
}
a[i][j] = 'foo'; // put something in the array cell
Note that this only works because we are always putting something in the new row array right after we create it. It might not work if you put 0 or "" in there instead of 'foo'.
There are a lot of things in javascript that are 'false' including 'null' and 'undefined' and '0' and I just don't know if an empty array or an array with one element that is an empty string are considered false. So you would have to do some experimenting with how, exactly to detect a missing row array so you can add it in.
Before fully defining my question, I must say that >>this question/answer<< doesn't answer my problem, and I have proven it to myself that the given answer doesn't match at all with the actual effect of property vs. variable or cached property (see below).
I have been using HTML5 canvas, and I write raw pixel blocks many times in a second in a 640x480 area.
As advised by some tutorials, it is good to cache the .data property of an ImageData variable (in this case, it would be _SCimgData).
If I cache that property in SC_IMG_DATA, I can putImageData repeatedly in the Canvas with no problem; but if I repeatedly access it directly with _ScimgData.data, the slow-down of the code is noticieable (taking nearly 1 second to fill a single 640x480 Canvas):
var SomeCanvas = document.getElementById("SomeCanvas");
var SCContext = SomeCanvas.getContext("2d");
var _SCimgData = SomeCanvas.getImageData(0, 0, 640, 400);
var SC_IMG_DATA = _SCimgData.data;
Now I have the following doubt:
Would my code be as slow for other kinds of similar accesses?
I need an array of objects for a set of functions that can have several "instances" of an object (created by a regular utility function), and that need the index of the instance in an array of objects, either to create/initialize it, or to update its properties.
My concrete example is this:
var objArray=new Array();
var objArray[0]=new Object();
objArray[0].property1="some string property";
for(var x=0; x<65536; x++)
doSomething(objArray[0].property1, objIDX=0);
Would that code become as unacceptably slow as in the Canvas case, if the properties and functions contained in some properties are called very intensively (several times in a single milisecond, of course using setInterval and several "timer threads" to avoid locking the browser)?
If so, what other alternative is there to speed up access for the different properties of several objects in the main object array?
EDIT 1 (2012-08-27)
Thanks for the suggestions. I have up-voted them since I suspect they will be useful for the project I'm working on.
I am thinking in a combination of methods, using mainly Arrays instead of Objects to build an actual array of "base objects", and addressing array elements by numbers (arr[0]) instead of string array keys (arr["zero"]).
var OBJECTS_SIZE=10
var Obj_Instances=new Array();
Obj_Instances[0]="property or array 1 of Object 0";
Obj_Instances[1]=new Array();
Obj_Instances[1][0]=new ArrayBuffer(128);
Obj_Instances[1][1]=new DataView(Obj_Instances[1][0]);
Obj_Instances[2]="property or array 3 of Object 0";
Obj_Instances[3]=function(){alert("some function here")};
Obj_Instances[4]="property or array 5 of Object 0";
Obj_Instances[5]="property or array 6 of Object 0";
Obj_Instances[6]=3;
Obj_Instances[7]="property or array 8 of Object 0";
Obj_Instances[8]="property or array 9 of Object 0";
Obj_Instances[9]="property or array 10 of Object 0";
Obj_Instances[10]="property or array 1 of Object 1";
Obj_Instances[11]=new Array();
Obj_Instances[11][0]=new ArrayBuffer(128);
Obj_Instances[11][1]=new DataView(Obj_Instances[11][0]);
Obj_Instances[12]="property or array 3 of Object 1";
Obj_Instances[13]=function(){alert("some function there")};
Obj_Instances[14]="property or array 5 of Object 1";
Obj_Instances[15]="property or array 6 of Object 1";
Obj_Instances[16]=3;
Obj_Instances[17]="property or array 8 of Object 1";
Obj_Instances[18]="property or array 9 of Object 1";
Obj_Instances[19]="property or array 10 of Object 1";
function do_Something_To_Property_Number_6(objIdx)
{
//Fix the index to locate the base address
//of the object instance:
///
objIdx=(objIdx*OBJECTS_SIZE);
Obj_instances[objIdx+6]++; //Point to "Property" 6 of that object
}
I would have, say an "instance" of an "object" that takes up the first 10 array elements; the next "instance" would take the next 10 array elements, and so on (creating the initialization in a custom "constructor" function to add the new block of array elements).
I will also try to use jsPerf and JSHint to see which combination result better.
To answer your "doubts", I suggest using JSPerf to benchmark your code. One can't really tell by code alone if the procedure is faster than another unless tested.
Also, I suggest you use the literal notation for arrays and objects instead of the new notation during construction:
var objArray=[
{
property : 'some string property'
}, {
...
},
];
Also, based on your code, it's better to have this since you are using the same object per iteration:
var obj = objArray[0].property1,
objIDX = 0;
for(var x=0; x<65536; x++){
doSomething(obj,objIDX);
}
I realise this is not quite answering your question (as it has already been answered), however as you seem to be looking for speed improvements in regard to function calls that happen thousands of times (as others who find this might also be doing). I thought I'd include this here as it goes against assumptions:
An example function:
var go = function (a,b,c,d,e,f,g,h) {
return a+b+c+d+e+f+g+h;
}
The following is how you would normally call a repetitive function:
var i=500000; while(i--){
go(1,2,3,4,5,6,7,8);
}
However, if none (or a few) of those arguments ever change for this particular usage of the function, then it's far better to do this (from a speed pov - obviously not an asynchronous pov):
var i=500000; go.args = [1,2,3,4,5,6,7,8];
while(i--){
go();
}
In order for the above to work you only need a slight modification to the original function:
var go = function (a,b,c,d,e,f,g,h, i) {
if ( go.args ) {
i = go.args;
a = i[0]; b = i[1];
c = i[2]; d = i[3];
e = i[4]; f = i[5];
g = i[6]; h = i[7];
}
return a+b+c+d+e+f+g+h;
}
This second function runs significantly faster because you are not passing in any arguments (a function called with no args is very quick to initiate). Pulling the values from the .args array doesn't seem to be that costly either (unless you involve strings). Even if you update one or two of the args it's still far faster, which makes it perfect for pixel or imagedata manipulations because you are normally only shifting x & y:
var i=500000; go.args = [1,2,3,4,5,6,7,8];
while(i--){
go.args[2] = i;
go();
}
So in a way this is an example of where an object property can be faster than local vars - if a little convoluted and off topic ;)
Possible browser optimizations notwithstanding, accessing a property of an object is more expensive than accessing a local variable (but not necessarily a global variable or a variable of a parent function).
The deeper the property, the more of a performance hit you take. In other words,
for(var x=0; x<65536; x++)
doSomething(objArray[0].property1, objIDX=0);
would be improved by caching objArray[0].property1, and not repeatedly assigning to objIDX:
var prop = objArray[0].property1;
objIDX = 0;
for(var x=0; x<65536; x++)
doSomething(prop, 0);
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;