在Javascript中移动多维数组的最佳方法是什么?

时间:2016-07-15 19:40:09

标签: javascript arrays multidimensional-array

我正在尝试创建一个javascript函数,将数组右移x个单位。它必须保持数组大小相同,并且必须为从多维数组移出的元素调用unloadChunk。这是我目前的实施:

function shift(x, y) {
    if (x > 0) {
        for (var i = 0; i < chunks.length; i++) {
            for (var j = chunks[i].length - 1; j >= 0; j--) {
                if(j + x > chunks[i].length - 1 && chunks[i][j]) {
                  unloadChunk(i, j);
                } 
                if (j < x) {
                    chunks[i][j] = null;
                }
                else {
                    chunks[i][j] = chunks[i][j - x];
                }
            }
        }
    }
    else if (x < 0) {
        for (var i = 0; i < chunks.length; i++) {
            for (var j = 0; j < chunks[i].length; j++) {
                if(j + x  < 0 && chunks[i][j]) {
                  unloadChunk(i, j);
                } 
                if (j - x >= chunks[i].length) {
                    chunks[i][j] = null;
                }
                else {
                    chunks[i][j] = chunks[i][j - x];
                }
            }
        }
    }
    if (y > 0) {
        for (var i = 0; i < chunks.length; i++) {
            if (i + y >= chunks.length) {
                for (var j = 0; j < chunks.length; j++) {
                  if(i - y < 0 && chunks[i][j]) {
                    unloadChunk(i, j);
                  }
                  chunks[i][j] = null;
                }
            }
            else {
                for (var j = 0; j < chunks.length; j++) {
                    if(i - y < 0 && chunks[i][j]) {
                      unloadChunk(i, j);
                    }
                    chunks[i][j] = chunks[i + y][j];
                }
            }
        }
    }
    else if (y < 0) {
        for (var i = chunks.length - 1; i >= 0; i--) {
            if (i + y < 0) {
                for (var j = 0; j < chunks.length; j++) {
                     if(i - y > chunks.length - 1 && chunks[i][j]) {
                       unloadChunk(i, j);
                     }
                    chunks[i][j] = null;
                }
            }
            else {
                for (var j = 0; j < chunks.length; j++) {
                     if(i - y > chunks.length - 1 && chunks[i][j]) {
                       unloadChunk(i, j);
                     }
                    chunks[i][j] = chunks[i + y][j];
                }
            }
        }
    }
}

如果您无法准确理解我想要的shift函数,请查看this fiddle并查看html输出。 我创建shift函数的尝试有效,但它有10个for循环。我的问题是,有没有更有效,更简洁的方法来做到这一点?

4 个答案:

答案 0 :(得分:1)

此提案使用

为了更好的可见性,我将null值替换为1000200030004000

function shift(x, y) {
    while (x > 0) {
        chunks.forEach(function (a) {
            a.pop();
            a.unshift(1000);
        });
        x--;
    }
    while (x < 0) {
        chunks.forEach(function (a) {
            a.shift();
            a.push(2000);
        });
        x++;
    }
    while (y > 0) {
        chunks.unshift(chunks.pop().map(function () { return 3000; }));
        y--;
    }
    while (y < 0) {
        chunks.push(chunks.shift().map(function () { return 4000; }));
        y++;
    }
}

function print(msg) {
    document.body.innerHTML += '<p>' + msg + '</p>';
}

function printarr(arr) {
    for (var i = 0; i < arr.length; i++) {
        print(JSON.stringify(arr[i]))
    }
}

var chunks = [[5, 3, 1], [9, 2, 5], [2, 3, 7]];

print("chunks: " + JSON.stringify(chunks));
shift(1, 0);
print("shifting right 1. chunks: "); printarr(chunks);
shift(-1, 0);
print("shifting left 1. chunks: "); printarr(chunks);
shift(0, 1);
print("shifting up 1. chunks: "); printarr(chunks);
shift(0, -1);
print("shifting down 1. chunks: "); printarr(chunks);

答案 1 :(得分:0)

您可以使用pop()push()shift()unshift()数组方法

var chunks = [
  [5, 3, 1],
  [9, 2, 5],
  [2, 3, 7]
];

function shiftDown(){
  chuck.pop();
  chuck.unshift(Array(3));
}

function shiftUp(){
  chuck.shift();
  chuck.push(Array(3));
}

function shiftRight(){
  chuck.foreach(function(v){
    v.pop();
    v.unshift(null);
  })
}

function shiftLeft(){
  chuck.foreach(function(v){
    v.shift();
    v.push(null);
  })
}

答案 2 :(得分:0)

如果正确解释问题,您可以使用{ "results": [ { "address_components": [ { "long_name": "43201", "short_name": "43201", "types": [ "postal_code" ] }, { "long_name": "Columbus", "short_name": "Columbus", "types": [ "locality", "political" ] }, { "long_name": "Franklin County", "short_name": "Franklin County", "types": [ "administrative_area_level_2", "political" ] }, { "long_name": "Ohio", "short_name": "OH", "types": [ "administrative_area_level_1", "political" ] }, { "long_name": "United States", "short_name": "US", "types": [ "country", "political" ] } ], "formatted_address": "Columbus, OH 43201, USA", "geometry": { "bounds": { "northeast": { "lat": 40.011147, "lng": -82.9723898 }, "southwest": { "lat": 39.976962, "lng": -83.0250691 } }, "location": { "lat": 39.9929821, "lng": -83.00122100000002 }, "location_type": "APPROXIMATE", "viewport": { "northeast": { "lat": 40.011147, "lng": -82.9723898 }, "southwest": { "lat": 39.976962, "lng": -83.0250691 } } }, "place_id": "ChIJ9Rz24rWOOIgR3EEuL2Ge4oo", "types": [ "postal_code" ] } ], "status": "OK" } Array.prototype.splice()

Array.prototype.forEach()

答案 3 :(得分:0)

  

它必须为应该设置为null的元素调用unloadChunk

当你在同一个数组上进行迭代时,改变一个数组并不是一个好主意。因此,将unloadChunk()更改为不更改chunks,但返回新值。

  

在我的情况下,我用新值填充所有空值。

那你为什么要先插入null - 值呢?为什么不插入新值?

//one-dimensional shift
function shift(arr, offset, callback){
    var i, j, len = arr.length;
    if(len && (offset |= 0)){
        typeof callback === "function" || (callback = function(v){return v});
        if(offset < 0){
            for(i=-offset,j=0; i<len;)arr[j++]=arr[i++];
            while(j<len)arr[j]=callback(null,j++,arr);
        }else if(offset){
            for(i=len-offset,j=len; i>0;)arr[--j]=arr[--i];
            for(i=0; i<j;++i)arr[i]=callback(null,i,arr);
        }
    }
    return arr;
}

//two dimensional shift
function shift2d(matrix, offsetX, offsetY, callback){
    var i, len = matrix.length, tmp, fn;
    offsetY |= 0;
    offsetX |= 0;
    if(len && matrix[0].length && (offsetY || offsetX)){
        typeof callback === "function" || (callback = function(v){return v});
        fn = function(val,j){ return callback(null, [i,j], matrix) };
        tmp = {length: matrix[0].length};
        offsetY && shift(matrix, offsetY, function(){return tmp});
        for(i = 0; i < len; ++i){
            if(matrix[i] === tmp){
                matrix[i] = Array.from(tmp,fn);
            }else{
                shift(matrix[i], offsetX, fn);
            }
        }
    }
    return matrix;
}

和代码:

var chunks = [[5, 3, 1], [9, 2, 5], [2, 3, 7]];

console.log(chunks);
console.log(shift2d(chunks, -1, 1));
console.log(shift2d(chunks, 1, -1, computeValue));

function computeValue(value, index, array){
    console.log("value: %o index: %o, is chunks: %o", value, index, array === chunks);

    //return the new value for this field
    return JSON.stringify(index);
    return Math.random();

    //with ES6 array destructuring:
    var [row,col] = index;
    return row*3 + col;
}

shift()shift2d()期望作为最后一个参数(返回新值)的(可选)回调函数。 出于一致性原因,我传递的参数与 Array.map 和其他

相同
  • :始终null,仅出于一致性原因
  • index :&#34; index&#34;访问。对于shift2d,这是一系列索引(请查看array destructuring
  • array :当前数组/矩阵。当它发生变化时,不要乱用它。传递这个论点的主要原因是检查你当前正在处理的数组。