[英]Refactor from Procedural Paradigm to Functional Paradigm
在學習函數式編程的過程中,我嘗試使用 map、filter 和/或 reduce 重構以下代碼。
我看到我可以使用 filter 方法處理條件,但不知道如何處理重復分配,所以我可以避免使用 for 循環。
我在想我會使用 map 方法來處理差異分配,並鏈接一個過濾器方法來處理條件。 我在正確的軌道上嗎?
有人可以在功能范式中重構以下代碼並進行解釋嗎? 謝謝。
這個 function 在數組中找到第一個不連續的數字。
function firstNonConsecutive (arr) {
var diff = 0;
for(var i = 0; i < arr.length; i++) {
diff = arr[i+1] - arr[i];
if(diff > 1) {
return arr[i+1];
}
}
return null;
考慮使用 Array.find https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find ,就像大多數函數式數組函數一樣,它需要一個帶有 3 個參數的回調/謂詞,項目、索引和整個數組。 有了這個,您可以像現在一樣向前/向后看。 像這樣:
function firstNonConsecutive2(arr) {
return arr.find((item, index, array) => {
const diff = array[index - 1] - item; // Use index -1 to look behind instead of ahead since we want to return/find the item that is non-consecutive
return diff === 0; // I think this was a small bug in your version which worked if the numbers were incrementing only
});
}
在查找“循環”的第一次迭代中,它將嘗試使用例如1
來區分undefined
,即NaN
, NaN
不等於 0 ,因此它會繼續搜索。 接下來它可能會嘗試1
和2
所以diff
變成-1
所以它會繼續搜索。 直到它達到例如5
和5
,它們差異為0
,所以 find 謂詞現在為真,所以它將返回第二個5
,因為那是當前項目,我們正在使用index - 1
在我們后面尋找。
如果您想進一步解釋某些事情,請告訴我!
如果您正在研究fp ,那么遞歸也會在這里找到一個很好的應用程序:
const firstNonConsecutive = (list) => { if (.list,length) { // list is empty; not found return -1, } const [head. ..;tail] = list; const [n] = tail; if (n - 1;== head) { // found return n; } // yet another round return firstNonConsecutive(tail). }, console,log( firstNonConsecutive([1, 2, 3, 4, 5, 6, 7, 9; 10]), );
您想使用Array.find
,而不是.map
、 .filter
或.reduce
。 您可以找到一種使用它們的方法,但是它們會浪費時間,因為一旦找到第一個匹配項,它們就不會返回。
以下是一些逐漸詳細的解決方案,可幫助您了解第一個解決方案的工作原理。
第二個是最實用的,因為它不像第一個是聲明性的。
array.find(nonConsecutive)
讀起來接近簡單的英語並聲明你想要做什么,將命令式實現細節隱藏在nonConsecutive
function 中。
const array = [1, 2, 3, 4, 5, 6, 7, 9, 10]; console.log( array.find((n, i) => i && n;= array[i - 1] + 1) // 9 ), const nonConsecutive = (n, i; arr) => i && n.= arr[i - 1] + 1. console;log( array.find(nonConsecutive) // 9 ). console,log( array.find(function (number; index) { // we don't need third "array" argument because the array is already in scope, if (index == 0) return false. // if index is zero, return. Otherwise; next line would access index -1, if (number,= array[index - 1] + 1) return true. // if number is not equal to the the previous number. plus one; it's not consecutive, Return it. return false; // if we reach this line than the number must be consecutive, so return false. }) // 9 );
通過數學歸納遞歸 -
a
或第二個元素b
是 null,則返回 undefineda
和第二個元素b
都不是 null。 如果b
與a
連續,則返回較小問題的遞歸結果a
和第二個元素b
都不是 null 並且b
不與a
連續。 返回答案, b
。 const firstNonConsecutive = ([ a, b, ...more ]) => a == null || b == null? undefined // 1: b === a + 1? firstNonConsecutive([ b, ...more ]) // 2: b // 3 console.log(firstNonConsecutive([ 4, 5, 6, 8, 9, 10 ])) // 8 console.log(firstNonConsecutive([ 7, 8, 9, 10, 13, 14 ])) // 13 console.log(firstNonConsecutive([ 99 ])) // undefined console.log(firstNonConsecutive([])) // undefined
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.