二維陣列應用題:陣列旋轉

2020-05-16
JS新手村

二維陣列簡單理解為一個陣列中的值有陣列型態
簡單的例子

1
2
3
const array = [[1,2,3],[4,5,6],[7,8,9]]
console.log(array[0][1]) //2
console.log(array[2][2]) //9

可以應用在一個有趣的試題

1
2
3
4
5
6
7
8
9

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

旋轉90度
7,4,1
8,5,2
9,6,3

方法一:陣列轉置後再倒轉(reverse)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const array = [[1,2,3],[4,5,6],[7,8,9]]
const newArray = [];

//進行轉置
for(let i = 0; i<array[0].length ; i++){
newArray[i]=[];
for(let j = 0 ; j<array.length ; j++){
newArray[i][j]=array[j][i];
}
}
console.log(newArray)
// [[1,4,7],
// [2,5,8],
// [3,6,9]

//再倒轉
for(let i =0;i<newArray.length; i++){
newArray[i].reverse();
}
console.log(newArray)
// [7,4,1]
// [8,5,2]
// [9,6,3]

思路

1
2
3
4
//原本的array
[1,2,3]
[4,5,6]
[7,8,9]

先將陣列轉置為:

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

轉置的步驟拆解:

觀察newarray第[0]列的順序就是array的每中的第[0]的值
第[0]列中有幾個值,等於迴圈要跑幾次(第[0]列的長度)

1
for(let i=0 ; i<array[0].length; i++)

此時i從0開始,
定義newArray的第[0]列中的值為陣列型態

1
newArray[i] = [];

開始為newArray第[0]列賦值
array本身陣列中有幾個值,等於迴圈要跑幾次

1
2
3
for(let j=0 ; j<array.length ; j++ ){
newArray[i][j] = array[j][i]
}
1
2
3
4
5
6
7
//組合
for(let i = 0; i<array[0].length ; i++){
newArray[i]=[];
for(let j = 0 ; j<array.length ; j++){
newArray[i][j]=array[j][i];
}
}

//依執行步驟演示一次,i,j直接以數字表示

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
//array[0].length = 3;
//array.length = 3;
for(let i = 0 ; i<3 ; i++){
newArray[0] = [];
for(let j=0 ; j<3 ; j++ ){
newArray[0][0] = array[0][0]
}
}
//繼續...
//i = 0 , j = 0+1 = 1
newArray[0][1] = array[1][0];
//i = 0 , j = 1+1 = 2
newArray[0][2] = array[2][0];
//i = 0 , j = 2+1 = 3 ; 3<3為false,j迴圈結束,i迴圈執行i++
//i = 0+1 = 1 , j = 0
newArray[1][0] = array[0][1];
//i = 0+1 = 1 , j = 0 + 1 = 1
newArray[1][1] = array[1][1];
.
.
.
//i = 2 , j = 1
newArray[2][1] = array[1][2];
//i = 2 , j = 2
newArray[2][2] = array[2][2];
//-------
//轉置完成,喜獲newArray
//[1,4,7]
//[2,5,8]
//[3,6,9]

再用reverse掉換順序

1
2
3
4
5
6
7
for(let i =0;i<newArray.length; i++){
newArray[i].reverse();
}
//調換完成,newArray再次變身
//[7,4,1]
//[8,5,2]
//[9,6,3]

DD後記:
沒有發現向右轉90度的呈現會和轉置再調換的一樣,其實一開始想的是方法二

方法二

1
2
3
4
5
6
7
8
9
array = 
[[1,2,3],
[4,5,6],
[7,8,9]]
//向右轉90度變成
newArray =
[[7,4,1],
[8,5,2],
[9,6,3]]

觀察array及要轉90度的newArray的規律

newArray裡的第[0]組陣列
newArray[0][0] = array[2][0]
newArray[0][1] = array[1][0]
newArray[0][2] = array[0][0]

newArray裡的第[1]組陣列(
newArray[1][0] = array[2][1]
newArray[1][1] = array[1][1]
newArray[1][2] = array[0][1]

newArray裡的第[2]組陣列
newArray[2][0] = array[2][2]
newArray[2][1] = array[1][2]
newArray[2][2] = array[0][2]

懶人包說明:
newArray第[0]列裡的值,等於array第[2][1][0]列中第[0]個值
newArray第[1]列裡的值,等於array第[2][1][0]列中第[1]個值
newArray第[2]列裡的值,等於array第[2][1][0]列中第[2]個值

有比較好嗎?

先以i, j分別替代值,會發現有這樣的規律:
newArray[ i ][ j ] = array[array.lenth -1 - j ][ i ]
[arrary.lenth -1 - j]會有點不直觀,必須一直找規律

其他迴圈跑的方式和方法一一樣,差別在不用再reverse()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
const newArray = [];
var len = array.length;

for (let i = 0; i < array[0].length; i++) {
newArray[i] = [];
for (let j = 0; j < array.length; j++) {
newArray[i][j] = array[len - 1 - j][i];
}
}
console.log(newArray)
//[7,4,1]
//[8,5,2]
//[9,6,3]
//完成任務!!

備註

  1. console.log出來會是一整列呈現,在此不多討論如何換行
  2. [arrary.lenth -1 - j]有好的解釋歡迎告訴我~

參考

【JS】轉置矩陣 #陣列