摘要:問題簡述給予一個多維數組和一個描述取值路徑的一維數組通過調用函數返回取值路徑描述的值,如原問題傳送門之所以想記錄一下是因為之前有在刷題的習慣,后來工作忙就怠慢了,今天閑來無事就準備刷幾道玩玩,然后就挑了一個比較簡單的中的難度評級的題。
問題簡述
給予一個多維數組和一個描述取值路徑的一維數組, 通過調用函數f返回取值路徑描述的值,如
f([[1, 2], [3, 4], [5, 6]], [0, 0]) -> 1
原問題傳送門
之所以想記錄一下是因為之前有在codewars刷題的習慣,后來工作忙就怠慢了,今天閑來無事就準備刷幾道玩玩,然后就挑了一個比較簡單的7kyu(codewars中的難度評級)的題。
因為這題比較簡單,我也沒多想,上來就干,仔細想了下,很容易嘛,不就是遞歸嗎?按大學老師教的來一套:
先找遞歸退出的條件,當路徑取到最后或者目標數組已經取盡(這里似乎題目沒有說清楚,暫定不對取值路徑做限定吧)
再找遞歸的模式, 如果不滿足遞歸退出的條件,則將目標數組縮小一維,傳遞新的取值路徑并遞歸
然后就有了第一版代碼
function getElement(array, indexes) { const idx = indexes.shift() if(indexes.length === 0 || array[idx].constructor !== Array ) return array[idx] else return getElement(array[idx], indexes) }
然后跑了跑作者提供的簡單測試用例,all passed,我就說嘛,這么簡單的題目不一把過豈不是有點丟臉,然后就直接點了提交,然后就蹦了一大片的failed測試用例出來,仔細看了看失敗的測試用例,并沒有看懂,因為都是很多莫名奇妙的數據,并且每次返回的結果都不一致(后來才知道是隨機的用例)。
之后一直以為是自己有一些邊界情況沒有考慮到,就前前后后又看了幾次自己的答案,并沒有發現什么大的問題,但是無論怎么提交都是失敗。之后前前后后大概看了15分鐘左右,突然就覺得是我自己把問題想簡單了。
因為最近一直在看函數式的東西,突然就聯想到,自己寫的這個函數,并不純。關于純函數是函數式編程中最基本的概念之一,所謂純既是要求函數沒有副作用,我這里的getElement使用了Array.shift方法,會對原數組進行修改,從而產生副作用。這么一想一下就和之前每次跑用例總是產生意想不到的結果的情況聯系上了,隨機用例的失敗原因一定是因為測試路徑會有很多個,但是測試目標數組只有一個,因此有副作用的話,只有第一次測試的結果是正確的,后面都會因副作用產生不同的結果。
既然是因為數組是引用類型而產生的問題,那么直接來一個深拷貝就可以了。因為這里只是答題,所以使用一個最簡單粗暴的深拷貝大法x => JSON.parse(JSON.stringify(x)),然后代碼就有了第二版代碼
function getElement(array, indexes) { array = JSON.parse(JSON.stringify(array)) indexes = JSON.parse(JSON.stringify(indexes)) const idx = indexes.shift() if(indexes.length === 0 || array[idx].constructor !== Array ) return array[idx] else return getElement(array[idx], indexes) }
之后提交,所有的用例都通過了。但是還沒有結束,因為自己的代碼在實現上還是挺啰嗦的,同時還使用了深拷貝大法,有沒有更簡單的方法呢?
有的。如果仔細思考一下,這里的解題的思路其實和Array.reduce的模式很像
對一個數組進行遍歷(對路徑數組進行遍歷)
每次遍歷返回一個值,并作為參數傳入下一次遍歷(對目標函數的降維)
在遍歷完成后,返回一個結果(取值路徑對應的值)
因此利用Array.reduce,這個問題一行代碼就可以解決,如下
function getElement(array, indexes) { return indexes.reduce((a, i) => a[i], array); }
同樣多考慮一下,它是純函數嗎?是的,它是純的。因為這里只做了取值的操作(a[i]),并不涉及任何的修改原數組的操作。這個答案也是在我提交后,所有答案中實現方案最好的一個。
當然還有其他的暴力破解法,我覺的想法也不錯,比如
function getElement(array, indexes) { return eval(`array[${indexes.join("][")}]`); }
還有利用spread運算符的方法,如
const getElement = (array,[index,...moreIndices]) => moreIndices.length ? getElement( array[index], moreIndices ) : array[index]
所以說工作累了,或者閑來無事,刷刷題還是挺有意思的,可以看見一些自己平時很熟悉但是在需要用時又難以想起的知識。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92220.html
摘要:這個時候查了下正則表達式的文檔文檔點擊這里,發現有一個方法,可以返回匹配成功的結果。那么我來總結下文章想表達的內容對于具有固定格式的字符串,可以考慮使用正則表達式來識別和匹配。 今天在認真干(劃)活(水)的時候,看到群里有人發了一道頭條的面試題,就順便看了一下,發現挺有意思的,就決定分享給大家,并且給出我的解決方案和思考過程。 題目如下: 實現一個get函數,使得下面的調用可以輸出正確...
摘要:這個時候查了下正則表達式的文檔文檔點擊這里,發現有一個方法,可以返回匹配成功的結果。那么我來總結下文章想表達的內容對于具有固定格式的字符串,可以考慮使用正則表達式來識別和匹配。 今天在認真干(劃)活(水)的時候,看到群里有人發了一道頭條的面試題,就順便看了一下,發現挺有意思的,就決定分享給大家,并且給出我的解決方案和思考過程。 題目如下: 實現一個get函數,使得下面的調用可以輸出正確...
摘要:這個時候查了下正則表達式的文檔文檔點擊這里,發現有一個方法,可以返回匹配成功的結果。那么我來總結下文章想表達的內容對于具有固定格式的字符串,可以考慮使用正則表達式來識別和匹配。 今天在認真干(劃)活(水)的時候,看到群里有人發了一道頭條的面試題,就順便看了一下,發現挺有意思的,就決定分享給大家,并且給出我的解決方案和思考過程。 題目如下: 實現一個get函數,使得下面的調用可以輸出正確...
摘要:不斷地窮舉下一步的可能性,直到最終達成目標。表示船在左邊表示船在右邊打印答案妖怪過河數僧人過河數船上是否安全左岸是否安全右岸是否安全過河后的數據過河后的數據簡單地看下深度優先搜索的函數,每次根據船所在的位置,枚舉下個狀態值。 無意中看到這么一道題,覺得很有意思,題目如下: 有三個和尚和三個妖怪要利用唯一的一條小船過河,這條小船一次只能載兩個人,同時,無論是在河的兩岸還是在船上,只要妖怪...
閱讀 3921·2021-11-17 09:33
閱讀 3283·2021-10-08 10:05
閱讀 3111·2021-09-22 15:36
閱讀 1140·2021-09-06 15:02
閱讀 2772·2019-08-29 12:45
閱讀 1590·2019-08-26 13:40
閱讀 3399·2019-08-26 13:37
閱讀 420·2019-08-26 13:37