Shifting rows and columns in 2D arrays - Javascript
我有这样的情况:
1 2 3 4 5 | var array = [ [1,2,3], [4,5,6], [7,8,9] ] |
我正在尝试创建一个移动一行或一列的函数,因此结果将是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | 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 循环,但我很想弄清楚这一点。请记住,我只编码了几个月。
这是我目前所拥有的。它最后给了我一个
1 2 3 4 5 6 7 8 9 | 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; } |
前面的答案看起来不错,但是在处理数组索引时缺少一个主要的东西;验证检查。
您不想尝试访问不存在的数组索引。因此,我创建了一个小类来根据需要移动您的数组,并进行验证。如果行或列索引无效,这将抛出
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | 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中看到。
鉴于这个问题:
高效地转置 javascript 数组
如果要实现
,只实现
1 2 3 4 5 6 7 8 9 10 11 12 | 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; } |
首先,您必须传递两个参数:数组和要移动的行/列。请记住,数组是从零开始的,而不是 1。所以在你的例子中,如果你想删除第一行,你需要传递 0,而不是 1。
其次,由于要将最后一个元素放在最前面,并将其他元素向下推,因此对于
1 2 3 4 5 6 7 8 9 10 | 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; } |
如您所见,它仅适用于您要移动的行,并且从末尾开始,一直到前面。在循环之前,我保存最后一个元素(将被覆盖)并将其放在循环末尾的第一个插槽中。
对于行移位,您可以使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | 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)) |