iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 28
0
自我挑戰組

菜鳥工程師的奇幻漂流:跟著kata活化手指和意識系列 第 28

Snail

今日kata

原始題目如下:(4kyu)
Given an n x n array, return the array elements arranged from outermost elements to the middle element, traveling clockwise.
https://ithelp.ithome.com.tw/upload/images/20201012/20128122lJ0ko9LCsQ.jpg

翻譯:
給一個nxn的陣列,想像將陣列元素一列一列填入方格中,回傳沿著順時鐘方向由外向內排列的元素。

範例:

array = [[1,2,3],
         [4,5,6],
         [7,8,9]]
snail(array) #=> [1,2,3,6,9,8,7,4,5]

構想&解法

snail = function(array) {
  let result = []
  while (array.length) {
    // 右
    result.push(...array.shift())
    // 下
    for (let i = 0; i < array.length; i++) {
      result.push(array[i].pop())
    }
    // 左
    result.push(...(array.pop()||[]).reverse())
    // 上
    for (let i = array.length - 1; i >= 0; i--) {
      result.push(array[i].shift())
    }
  }

  return result
}

將原始陣列array的元素一一shift()或是pop()放入result陣列中。如下圖:
https://ithelp.ithome.com.tw/upload/images/20201012/2012812297Z2byd4gt.jpg

可以分成『右』『下』『左』『上』四個部分:

  • 右: 第一個橫列由左至右的全部元素,array.shift()回傳array第一個元素
  • 下: 每一列的最後一個元素,array[i].pop()回傳array[i]的最後一個元素
  • 左: 最後一個橫列由右至左的元素,array.pop().reverse()回傳array最後一個元素
  • 上: 每一列的第一個元素,array[i].shift()回傳array[i]第一個元素

拆解如下:
https://ithelp.ithome.com.tw/upload/images/20201012/201281225JHbAEh8Tr.jpg

array.shift()array.pop()會移除array中的元素,故最後array沒有剩下任何元素即代表完成!


其他解法觀摩

function snail(array) {
  var vector = [];
  while (array.length) {
    vector.push(...array.shift());
    array.map(row => vector.push(row.pop()));
    array.reverse().map(row => row.reverse());
  }
  return vector;
}

完美搭配shift() pop()reverse(),把原本要分四個部分的『右、下、左、上』,利用矩陣反轉後重複執行array.shift()row.pop()! /images/emoticon/emoticon02.gif


整理用法

以下內容及範例摘自MDN web docs-Array

陣列.shift()

語法:arr.shift(),移除並回傳陣列第一個元素,會改變陣列長度。

範例:

var myFish = ['angel', 'clown', 'mandarin', 'surgeon'];
var shifted = myFish.shift(); 

console.log('myFish after:', myFish); 
// myFish after: ['clown', 'mandarin', 'surgeon']

console.log('Removed this element:', shifted); 
// Removed this element: angel

陣列.unshift()

語法:arr.unshift(element1[, ...[, elementN]]),增加一個或多個元素到陣列的最前端,回傳陣列新長度。

範例:

const array1 = [1, 2, 3];

console.log(array1.unshift(4, 5));
// expected output: 5

console.log(array1);
// expected output: Array [4, 5, 1, 2, 3]


陣列.pop()

語法:arr.pop(),移除並回傳陣列最後一個元素,會改變陣列長度。

範例:

var myFish = ['angel', 'clown', 'mandarin', 'sturgeon'];
var popped = myFish.pop();
console.log(myFish); // ['angel', 'clown', 'mandarin' ] 
console.log(popped); // 'sturgeon'

陣列.push()

語法:arr.push(element1[, ...[, elementN]]),增加一個或多個元素到陣列的末端,回傳陣列的新長度。

範例:

var sports = ['soccer', 'baseball'];
var total = sports.push('football', 'swimming');

console.log(sports); // ['soccer', 'baseball', 'football', 'swimming']
console.log(total);  // 4

陣列.reverse()

語法:a.reverse(),反轉陣列,將第一個元素變成最後一個元素,最後一個元素變成第一個。陣列本身會被改變。

範例:

var a = ['one', 'two', 'three'];
var reversed = a.reverse(); 

console.log(a);        // ['three', 'two', 'one']
console.log(reversed); // ['three', 'two', 'one'] 參考a的位址

以上為今日分享的內容,若有錯誤或是建議,請再隨時和我聯繫。


上一篇
Equal Sides Of An Array
下一篇
Sudoku Solution Validator
系列文
菜鳥工程師的奇幻漂流:跟著kata活化手指和意識30

尚未有邦友留言

立即登入留言