簡體   English   中英

從程序范式重構為功能范式

[英]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 ,即NaNNaN不等於 0 ,因此它會繼續搜索。 接下來它可能會嘗試12所以diff變成-1所以它會繼續搜索。 直到它達到例如55 ,它們差異為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 );

通過數學歸納遞歸 -

  1. 如果第一個元素a或第二個元素b是 null,則返回 undefined
  2. (歸納)第一個元素a和第二個元素b都不是 null。 如果ba連續,則返回較小問題的遞歸結果
  3. (歸納)第一個元素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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM