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;
}
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
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.
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);
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.
Related
Just wondering, what is the most efficient way to divide an array by a scalar? I can clearly loop over it, but efficiency is paramount in my case.
Common trivial way:
var array_2 = []
var array_1 = [original_data
var divisor = my_scalar
for(var i = 0, length = array.length; i < length; i++){
array_2.push(array[i]/divisor)
}
Any trick I can use (or a new approach altogether)?
You've said you want the most efficient way. Fairly sure what you're doing is close, but you want assignment rather than push, and in at least some JavaScript engines (V8 for instance, in the Chromium browsers), if you tell the Array constructor an initial length, they'll pre-allocate backing storage (even though the array starts with no elements in it):
var array_2 = Array(array.length);
for(var i = 0, length = array.length; i < length; i++){
array_2[i] = array[i] / divisor;
}
Having said that: The difference between that and map is going to be very very very very very very small and it's an exceptionally rare use case where it would matter. Whereas map is clear, simple, short...
const numbers = [350,451,758,456,999];
const dividedNum = num => num/7;
const output1 = numbers.map(dividedNum);
console.log(output1)
You could use map for that:
var newData = data.map(function(item) { return item/scalar } )
New to JS here. How can I use math.js or vanilla js to return an array where a 2d array is multiplied by each column. The size of the 2 arrays will always be the same.
[[2,2],
[2,4]]
results is
[4,8]
I have tried:
adjustedrating = [[2,2],[2,4]]
var w = adjustedrating.length;
for (var i = 0, len = adjustedrating[0].length; i < len; i++) {
var multiple = adjustedrating[0][i];
for (var j = 0; j < w; j++) {
multiple *= adjustedrating[j][i];
}
both.push(multiple);
};
What you can do is loop through the outer array, and store the results of the multiplication as you go. For instance:
// The two dimensional array
var twoDimArray = [[2,2],
[2,4]];
// We'll say this is where your results will go. It will be the same length
// as one of your inner arrays, and all values will start at 1
var results = [1,1];
// Loop through the 2D Array
for( var outerIndex = 0; outerIndex < twoDimArray.length; outerIndex++){
// Loop through the currently selected inner array
for( var innerIndex = 0; innerIndex < twoDimArray[outerIndex].length; innerIndex++){
// Multiply appropriate result by the appropriate value
results[innerIndex] *= twoDimArray[outerIndex][innerIndex];
}
}
// Simply displays the results somewhere
document.getElementById('results').innerHTML = results;
<div id="results"></div>
I am looking at an underscore.js function to retrieve the values from an object and am curious to understand the reason the _.values function was created the way it was.
The function as is in underscore.js:
_.values = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var values = Array(length);
for (var i = 0; i < length; i++) {
values[i] = obj[keys[i]];
}
return values;
};
I believe this would also work however:
_.values = function(obj) {
var keys = _.keys(obj);
var length = keys.length;
var values = [];
for (var i = 0; i < length; i++) {
values.push(obj[keys[i]]);
}
return values;
};
What is the tradeoff between using function #1 vs. #2. Is it simply for performance or is there other things?
Thanks.
The first approach allows the JS runtime to immediately allocate the correct amount of memory.
Calling push() on an empty array will force the array to resize as it gets full, wasting time and memory.
I have an array and I want to overwrite all values in it (that are all numbers) with a 0. So the array already exists.
I can do this with a for loop. However, is there a fill() call of some kind like the Java Arrays.fill()?
A very simple for-loop is all you need. There's no fill-function in JavaScript.
var length = arr.length,
for (var i = 0; i < length; i++) {
arr[i] = 0;
}
You can use map for this.
var arr = [1,2,3];
arr = arr.map(function() {return 0});
//arr = [0, 0, 0]
The performance may be worse than a plain for loop.
I have the length of my previous object and i need to create a new array of objects based on the length with new key's.
Length = 3;
var newArray = [];
for(var i =0; i <3; i++){
var Object = {};
Object['newKey'] = 1;
newArray.push(Object);
}
This would eventually create newArray of Objects whose length is 3 containing something like this.. newArray[0],[1],[2].
Am i doing this correctly, please do suggest me if anything wrong or a better way to do this.
Here's what you wrote (I think), just shortened a bit (and fixed the capitalization of variable names)
var length = 3;
var newArray = [];
for( var i = 0 ; i < length ; i++ ) {
newArray.push({newKey: 1});
}
but to be honest it's unclear to me exactly what you're trying to accomplish
You could make it slightly more dynamic by referencing the variable for length.
Example updated per comments:
var length = 3,
newArray = [];
for ( var i=0; i<length; i++ ) {
var tempObj = {};
tempObj['newKey'] = 'SomeValue';
newArray.push(tempObj);
}
I didn't really do more than clean up what you have.