9

Is there a faster way to create and zero out a matrix?
Currently, my code involves two for loops:

var nodes = new Array(ast.length);

for (var i=0; i < nodes.length; i++){
    nodes[i] = new Array(ast.length);
    for (var j=0; j < nodes.length; j++)
        nodes[i][j]=0;
}
1

5 Answers 5

5

You could use the Array.prototype.fill method:

var nodes = Array(ast.length).fill(Array(ast.length).fill(0));

jsperf test: http://jsperf.com/fill-array-matrix

Sign up to request clarification or add additional context in comments.

6 Comments

Note fill() is not fully supported.
I think this will also be slower than the OPs code, but it is comparable.
Note to OP: .fill() is not universally supported yet. There appears to be no support in IE or iOS7 and not great support in Android. You could use a polyfill, but don't expect the polyfill to be fast. So, basically this could speed you up in Chrome, Firefox and Edge.
No doubt it is fast in initializing, the problem with this approach is, if I decide to change a single cell value, lets say nodes[0][4] = 1, it will change the 4th column to 1 for all the rows.
This needs to be downvoted more. It's incorrect to have identical rows.
|
3

Since you asked for "faster", it looks like you can gain some speed by creating a single initalized array and then using .slice() to copy it rather than initializing each array itself:

var nodes = new Array(ast.length);
var copy = new Array(ast.length);
for (var i = 0; i < ast.length; i++) {
    copy[i] = 0;
}

for (var i=0; i < nodes.length; i++){
    nodes[i] = copy.slice(0);
}

jsperf test: http://jsperf.com/slice-vs-for-two-d-array/2

This method looks to be 10-20% faster in all three major browsers.

enter image description here

Comments

3

You can create array of zeros once and create copies of it:

var length = 10;

var zeros = Array.apply(null, Array(length)).map(Number.prototype.valueOf, 0);
var nodes = zeros.map(function(i) {
    return zeros.slice();
});

console.log(nodes);

2 Comments

Your code shows a length of 10, but you claim 1000x1000. I think you need to publish your measurement technique to believe array fill is 0ms and your solution is 4ms vs. 1492ms for the double for loop. That seems like too much difference to me to be right. If so, great. But, without more documentation, it's a bit hard to believe.
Thanks. Your solution's and @jfriend00 's running times are almost same.
0

I don't know how fast this is in terms of producing a 2d array but it is IMHO a better way that most.

Array.prototype.dim = function(){
    if( this.length==2 ){
        r=this.shift(); c=this.shift();
        while( r-- ) this.push( new Array( c ).fill(0,0) );
        return this;
    }
}

In use, the 2d array is made by initialising a regular 1d array with the parameters of x,y or rows, cols as two parameters. These are then used to dimension the array and fill it with zeros at the same time.

var arr = new Array(5,7).dim();
console.log(arr[4]);

The array then has got the desired dimension with zeros.

The output:

console.log(arr[4]);
 (7) [0, 0, 0, 0, 0, 0, 0]

I hope someone finds this useful.

Comments

0

Heres a fast one liner:

const len1 = 3
const len2 = 4

const x = [...Array(len1)].map(() => Array(len2).fill(0));

x[1][2] = 7 // only a single cell affected
console.log(x)

This creates an array of len1 (using the spread operator with Array(len1)), and then maps each element to a new array of length len2 filled with zeros.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.