簡體   English   中英

在2D數組中移動行和列-Javascript

[英]Shifting rows and columns in 2D arrays - Javascript

我有這樣的情況:

var array = [
  [1,2,3],
  [4,5,6],
  [7,8,9]
]

我正在嘗試創建一個可移動行或列的函數,因此結果將是:

shiftRow(array, 1) 

[
  [3,1,2],
  [4,5,6],
  [7,8,9]
]

shiftColumn(array,1)

[
  [7,2,3],
  [1,5,6],
  [4,8,9]
]

我希望第一個數字是最后一個數字,然后在任何情況下都從那里繼續。 我已經嘗試了幾個嵌套的for循環,但是我很想弄清楚這一點。 請記住,盡管我只編碼了幾個月。

到目前為止,這就是我所擁有的。 最后,它給了我一個undefined錯誤,並且以錯誤的方式移動了它。

function shiftRow(arr) {
  var temp = arr
  for(var i = 0; i < temp.length; i++) {
    for(var j = 0; j < temp[i].length; j++) {
      temp[i][j] = temp[i][j+1]
    }
  }
  return temp;
}

以前的答案看起來不錯,但缺乏與數組索引處理時,一個重大的事情; 驗證檢查。

您不想嘗試訪問不存在的數組索引。 因此,我創建了一個小類來根據需要對數組進行驗證。 如果行或列索引無效,則將引發Error

class ArrayShifter {
    static showArray(array) {
        // console.log("Array : ", array);
        console.log('------');
        for (const [index, elem] of array.entries()) {
            console.log(''+elem);
        }
    }

    static validateRowIndex(array, rowIndex) {
        if (!isArray(array) || !isInt(rowIndex) || rowIndex <= 0 || rowIndex > array.length) {
            throw new Error('The row index is wrong');
        }
    }

    static validateColumnIndex(array, columnIndex) {
        if (!isArray(array) || !isInt(columnIndex) || columnIndex <= 0 || columnIndex > array[0].length) {
            throw new Error('The column index is wrong');
        }
    }

    static shiftRow(array, rowIndex) {
        ArrayShifter.validateRowIndex(array, rowIndex);
        array[rowIndex - 1].unshift(array[rowIndex - 1].pop());

        return array;
    }

    static shiftColumn(array, columnIndex) {
        ArrayShifter.validateColumnIndex(array, columnIndex);
        let prev = array[array.length - 1][columnIndex - 1];

        for (const elem of array) {
            let tmp = elem[columnIndex - 1];
            elem[columnIndex - 1] = prev;
            prev = tmp;
        }

        return array;
    }
}

let sourceArray1 = [
    [1,2,3],
    [4,5,6],
    [7,8,9],
];
let sourceArray2 = [
    [1,2,3],
    [4,5,6],
    [7,8,9],
];
let controlArrayShiftRow = [
    [3,1,2],
    [4,5,6],
    [7,8,9],
];
let controlArrayColumnRow = [
    [7,2,3],
    [1,5,6],
    [4,8,9],
];

// arrayShifter.showArray(sourceArray1);
console.log(`Shift row test is ${areArraysEqual(controlArrayShiftRow, ArrayShifter.shiftRow(sourceArray1, 1))}.`);

// arrayShifter.showArray(sourceArray2);
console.log(`Shift column test is ${areArraysEqual(controlArrayColumnRow, ArrayShifter.shiftColumn(sourceArray2, 1))}.`);




//-------------------- Unimportant js functions --------------------
function isArray(arr) {
    if (Object.prototype.toString.call([]) === '[object Array]') { //Make sure an array has a class attribute of [object Array]
        //Test passed, now check if is an Array
        return Array.isArray(arr) || (typeof arr === 'object' && Object.prototype.toString.call(arr) === '[object Array]');
    }
    else {
        throw new Exception('toString message changed for Object Array'); //Make sure the 'toString' output won't change in the futur (cf. http://stackoverflow.com/a/8365215)
    }
}
function isInt(n) {
    return typeof n === 'number' && parseFloat(n) === parseInt(n, 10) && !isNaN(n);
}
function areArraysEqual(a1, a2) {
    return JSON.stringify(a1) == JSON.stringify(a2);
}

工作代碼都可以在此看到codepen

對於行移位,可以使用Array#unshiftArray#pop方法。 為了移動列,請使用帶有temp變量的Array#forEach方法。

 var array = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ], array1 = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] function shiftRow(arr, row) { arr[row - 1].unshift(arr[row - 1].pop()); return arr; } function shiftCol(arr, col) { var prev = arr[arr.length - 1][col-1]; arr.forEach(function(v) { var t = v[col - 1]; v[col - 1] = prev; prev = t; }) return arr; } console.log(shiftRow(array, 1)) console.log(shiftCol(array1, 1)) 

首先,您必須傳遞兩個參數:數組和要移動的行/列。 並請記住,數組是從零開始的,而不是從1開始的。因此,在您的示例中,如果要拉第一行,則需要傳遞0,而不是1。

其次,由於您想將最后一個元素放在最前面,並向下推其他元素,因此需要從后到前循環循環shiftRow 這是一個解決方案。 隨時進行改進。

function shiftRow(arr, row) {
  var temp = arr[row];
  var j=temp.length-1;
  var x=temp[j];
  for(var i = j; i > 0; i--) {
    temp[i]=temp[i-1];
  }
  temp[0]=x;
  arr[row]=temp;
}

如您所見,它僅在您要移動的行上起作用,並且從末尾開始一直到最前面。 在循環之前,我保存最后一個元素(將被覆蓋)並將其放在循環末尾的第一個插槽中。

鑒於這個問題:

有效地轉置javascript數組

這足以只實現shiftRow和其前后調換,如果我們要實現shiftCol

function shiftRow(array,n)
{
  let retVal=[[]];
  for(i=0;i<array.length;i++)
  {
    if (i==n)
      retVal[i]= array[i].slice(1,array.length).concat(array[i][0]);
    else
      retVal[i]=array[i];
  }
  return retVal;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM