5 kyu
刪除陣列中沒必要的相反方向;
例如往北走後又往南;往西走後又往東。
驗證陣列元素是否有前後衝突。
如果有衝突就過濾掉目前迭代的元素,以及下一個。
for loop i < arr.legnth
if(arr[i] == "") target = "..."
if(arr[i+1] === target) delete arr[i+1]
else
i++
for loop end
return arr;
function dirReduc(arr) {
let target;
let now = 0;
while (now < arr.length) {
if (arr[now] == "NORTH") target = "SOUTH";
if (arr[now] == "SOUTH") target = "NORTH";
if (arr[now] == "EAST") target = "WEST";
if (arr[now] == "WEST") target = "EAST";
if (arr[now + 1] === target) {
arr.splice(now + 1, 1);
arr.splice(now, 1);
return dirReduc(arr);
}
now++;
}
return arr;
}
target 紀錄目前方向不應該走的,例如東紀錄西。
now 代表從起點開始 while 迴圈,前往陣列一個個的方向;並且依照目前要前往的位置,改動 target 的內容,並且比對下一位 now+1 是否與 target 相同。
如果相同:
刪除目前的所在位置、以及下一個要前進的方向;用遞迴的方式呼叫,並且帶入被改動後的陣列。
如果不同:表示目前方向沒有問題,now++ 前進。
最後返回 arr 的結果。
function dirReduc(plan) {
var opposite = {
'NORTH': 'SOUTH', 'EAST': 'WEST', 'SOUTH': 'NORTH', 'WEST': 'EAST'};
return plan.reduce(function(dirs, dir){
if (dirs[dirs.length - 1] === opposite[dir])
dirs.pop();
else
dirs.push(dir);
return dirs;
}, []);
}
opposite 直接紀錄衝突的位置。
用 reduce 迭代路線,起始值會傳入一個空陣列。
如果被累加值的最後尾存在衝突,就從 dirs 刪除掉元素;否則 push 目前的元素。
最後把 dirs 返回給下一輪,直到跑完迴圈。
以傳入參數為:["NORTH", "SOUTH", "SOUTH", ...]
為例拆解 reduce 幾個步驟。
[]
。[]
,dir 為 NORTH 對應 opposite 的 SOUTH。["NORTH"]
。["NORTH"]
,dir 為 SOUTH 對應 opposite 的 NORTH。[]
。依此類推。
我通常在解完題之後都會看一下最佳解,所以也才在鐵人賽放到文章裡記錄下來。
本次的最佳解 reduce 的運用方式,也讓我學到了一種思路~