最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Fastest way to reset a multidimensional array? - Stack Overflow

programmeradmin6浏览0评论

Say I have a two dimensional array: vectors[x][y], and the initial array structure looks like this:

vectors = [    
 [0, 0, 0, 0, 0,],
 [0, 0, 0, 0, 0,],
 [0, 0, 0, 0, 0,],
 [0, 0, 0, 0, 0,],
 [0, 0, 0, 0, 0,]
]

After some calculations, the data in the array is randomized. What is the fastest way and most efficient way to return the array to it's initial state?

I know that I could just hardcode the above zeroed array and set vectors equal to it again, but I also know that an algorithm such as:

for (var x = 0; x < vectors.length; x++) {
    for (var y = 0; y < vectors[x].length; y++) {
        vectors[x][y] = 0;
    }

}

is O(x * y).

So which is the better way? And is there a better, even faster/more efficient way to solve this?

And for the general case of zeroing a multi-dimensional array of any length, which is the best way? (I'm working in JavaScript if it matters)

Say I have a two dimensional array: vectors[x][y], and the initial array structure looks like this:

vectors = [    
 [0, 0, 0, 0, 0,],
 [0, 0, 0, 0, 0,],
 [0, 0, 0, 0, 0,],
 [0, 0, 0, 0, 0,],
 [0, 0, 0, 0, 0,]
]

After some calculations, the data in the array is randomized. What is the fastest way and most efficient way to return the array to it's initial state?

I know that I could just hardcode the above zeroed array and set vectors equal to it again, but I also know that an algorithm such as:

for (var x = 0; x < vectors.length; x++) {
    for (var y = 0; y < vectors[x].length; y++) {
        vectors[x][y] = 0;
    }

}

is O(x * y).

So which is the better way? And is there a better, even faster/more efficient way to solve this?

And for the general case of zeroing a multi-dimensional array of any length, which is the best way? (I'm working in JavaScript if it matters)

Share Improve this question asked Nov 7, 2012 at 18:27 chrisdotcodechrisdotcode 1,6012 gold badges18 silver badges22 bronze badges 7
  • 1 possibly related: stackoverflow./questions/1295584/… – lc. Commented Nov 7, 2012 at 18:29
  • Have you tried both approaches and profiled each of them? – Dai Commented Nov 7, 2012 at 18:30
  • @lc. I'll always know the length of the array(s) beforehand, and they're be initialized by hand. For the particular case of my question, the array is a 5x5. – chrisdotcode Commented Nov 7, 2012 at 18:31
  • 1 Why are we worried about the Big-O performance for a 5x5 array? You could unroll the entire nested loop I suppose. – A. Webb Commented Nov 7, 2012 at 18:35
  • @A.Webb: because of the pure theoretical interest! (which is why I also asked for the general case) – chrisdotcode Commented Nov 7, 2012 at 18:36
 |  Show 2 more ments

4 Answers 4

Reset to default 3

Here is my two cents:

I'd go with keeping a clean copy of your original array for fastest performance. You can either keep a referenced hard-coded copy

var vectorsOrig = [    
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0],
 [0, 0, 0, 0, 0]
];

or do a dynamic clean clone of the initial array using slice ((recursively in your case for deep copy):

var clonedVectors = [0, 0, 0, 0, 0].slice(0);

Regardless, taking the approach of resetting your vector reference to an original copy will be faster than cycling through and resetting each node. If your old vector array object isn't referenced any more, JavaScript will garbage collect it.

With that said, the question bees of obtaining a clean copy each and every time. Having once hard-coded instance will give you one clean copy and you'll have to clone it thereafter. Nor do you want to into dynamic generation via similar for loops as the reset option. My advice is to write a clone function that simply returns a new hard-coded or initialized array:

function newVector() {
    return [    
     [0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0],
     [0, 0, 0, 0, 0]
    ];
}
var vector = newVector();
vector[1][2] = 11;
console.dir(vector);
vector = newVector();  // your old array will be garbage-collected if no longer referenced by any other reference
console.dir(vector);

Ideally, it's best to benchmark various approach.

EDIT Thanks to Vega's input, I've modified his test to test three approaches. In Chrome and IE9, this solution seems to be the fastest, in FF (15.0.1) manual iteration seems faster (memory allocation/management slower in FF possibly). http://jsperf./array-zero-test/2

So far, it sounds like we have 2 possible choices.

  1. Overwrite the whole thing with zeroes. (Your solution)

  2. Keep a record of all modified elements and only reset those ones. record[0].x = 3; record[0].y = 5; and so on However, you'll still need to loop once through the record. To explain it further, I mean that each time an element in the array is set to a value, you should record that element's placement in the array. Then, using a loop, you can visit each element and set it to 0. So, if you had a sparse array, it would be more efficient.

Depending on the implementation, I can see why you would want #2 instead of #1...but if you seriously have a large enough matrix that you need to worry about analyzing the algorithm, you might consider doing some kind of server pre-processing.

Another different way of looking at the problem is to use a linear array and calculate the linear index from the x, y indices when you do your updates.

The initialization is then just a single for loop with time O(x+y)

I'll risk and say that the fastest way of assigning the same value to all elements is by calling Array.map().

But, there is a catch here. Note that this will have incredibly fast performance on browsers that have natively implemented that method, and will have just the usual performance in other browsers. Also note that .map() isn't available in some old browsers, so you'll need to use Underscore.js or any other library that provides that method.

发布评论

评论列表(0)

  1. 暂无评论