Constructor for two dimensional array [duplicate] - javascript

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

Related

Fastest way to get all the same elements from an array existing in an other one [duplicate]

This question already has answers here:
Simplest code for array intersection in javascript
(40 answers)
Closed 3 years ago.
I need a faster way to get all the same elements from an array existing in another one.
I have two really large arrays (A and B) with Date objects (>100k elements).
Array B contains a subset from elements in Array A.
I need Array A filtered for elements that are contained in Array B.
So, why not just use Array B directly? I need to preserve the reference from Array A.
Currently I'm using this code:
const A = [];
const B = [];
const result = A.filter((s) => {
return B.indexOf(s) !== -1;
});
This way is quite slow. It needs over 2min to perform that action with my arrays.
Turn the B array into a Set first. Set#has is O(1), but Array#indexOf / Array#includes is O(n):
const bSet = new Set(B);
const result = A.filter(item => bSet.has(item));
That'll improve performance a ton. You might be able to make it a tiny bit faster by using a for loop instead of filter, but the improvement will probably be pretty small.
This works when both arrays contain primitives or contain references to the same objects. If the objects are different, neither .indexOf nor .has nor .includes will work, in which case the strategy would be to somehow serialize all of the objects in B to a Set of primitives first, then carry out the same operation when iterating over A to see whether it's included in B.
If you have flexibility with the types, you can always have B contain a pointer to a parent A, this you don't need to search through all of the sub elements of an A to deterrmine if you will find B there - but I am not certain if a B can have multiple A etc etc...

Javascript - Performing actions on Array elements on creation [duplicate]

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.

Creating Array in Javascript [duplicate]

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:

What parameter include in the parenthesis of JavaScript array? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Since I am into the basics of JavaScript I am able to create array, but I want to know what we might include in the parenthesis of array like test=new Array("parameter?"); so I meant what to include as parameter of that javascript array
The array constructor is overloaded and which result you get depends on how many arguments you pass and of which data type they are:
More than one argument (any type):
var arr = new Array(1,2,3,4);
Creates a new array containing the values passed to the constructor.
One argument ...
... of type number:
var arr = new Array(4);
Creates an empty array and sets its length to the number passed as argument. The array appears to have 4 elements (because its length is 4) but it does not contain any elements (e.g. arr[0] will be undefined).
... any other type:
var arr = new Array('foo');
Creates an array containing one element, the argument passed to the constructor (the same as passing multiple arguments).
Because of this ambiguity of the Array constructor function, you should avoid it and use array literals instead:
var arr = [1,2,3,4];
That said, to learn the basics, read the MDN JavaScript Guide, especially about arrays.
First, if you find yourself writing new Array, there's probably a better way to do it. But first I'll explain the Array constructor and then talk about better ways.
The Array constructor has two forms: A form that takes zero or one arguments (if that one argument is a number), and a form that takes more than one argument (or just one argument if the argument is not a number). Never use the second form, and avoid using the first one.
The first form:
var a = new Array(5);
...creates an array with a length of 5 which has no entries (JavaScript arrays are "sparse," because they're not really arrays at all — more on that below). If you don't supply any argument at all, the length is 0.
The second form:
var a = new Array(5, 6);
...creates an array with as many entries as there are arguments (so, two in this case) and uses the arguments to set the values of those entries.
Note that both the number and type of arguments is important:
var a = new Array(5); // Creates an array with length = 5 with no entries
var b = new Array("5"); // Creates an array with length = 1 and entry [0] = "5"
It's almost always much better to use array literals.
The first form above, done with an array literal instead:
var a = [];
a.length = 5;
The second form above, done with an array literal instead:
var a = [5, 6];
Using array literals is "better" (in my view) for several reasons, some of which are more subjective than others:
It's clearer, and doesn't have the ambiguity that the Array constructor has. For instance, what does this do?
var a = new Array(foo);
Answer: It depends (on what foo has it in it, a number or something else). This is just Not Goodtm.
It's not susceptible to someone overwriting the Array symbol (which they can do) with something else.
It's more concise and expressive (this is probably the most subjective of the reasons).
More reading:
The ECMAScript (JavaScript) specification on Arrays
A myth of arrays (in my blog), which explains how JavaScript arrays aren't arrays
You are in learning curve. See here. You can write array items there.
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Array (Need editorial review)
Syntax Reference
[element0, element1, ..., elementN]
new Array(element0, element1, ..., elementN)
new Array(arrayLength)
MDN Tutorial

What are the speed diferences between object's property access and normal variable access?

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);

Categories