1

我一直試圖使用Ramda.js使用無點方法將我的原始解決方案重構爲getPermutations()函數。是否有可能進一步重構它,朝着一種無點風格的方式進行重構。看起來我只是做了一個更大的混亂。此外,當我運行測試時,重構版本中存在一個錯誤:TypeError:reduce:list必須是數組或可迭代的。使用遞歸,Ramda.js和無點式重構getPermutations()

原來的解決方案:

// getPermutations :: String -> [String] 
function getPermutations(string) { 
    function permute(combination, permutations, s) { 
    if (!s.length) { 
     return permutations[combination] = true; 
    } 

    for (var i = 0; i < s.length; i++) { 
     permute(combination.concat(s[i]) 
      , permutations 
      , (s.slice(0, i) + s.slice(i+1)) 
      ); 
    } 
    return Object.keys(permutations); 
    } 

    return permute('', {}, string); 
} 

我試圖重構與Ramda.js:

var _ = require('ramda'); 

// permute :: String -> {String: Boolean} -> String -> [String] 
var permute = _.curry(function (combination, permutations, string) { 
    // callPermute :: String -> ({String: Bool} -> Char -> Int -> String) -> IO 
    var callPermute = function (combination) { 
    return function (acc, item, i, s) { 
     return permute(_.concat(combination, item) 
        , acc 
        , _.concat(_.slice(0, i, s), _.slice(i + Infinity, s)) 
        ); 
    }; 
    }; 

    var storeCombination = function() { 
    return permutations[combination] = true; 
    }; 

    // should be an ifElse, incorporating compose below 
    _.when(_.not(string.length), storeCombination); 

    return _.compose(_.keys 
        , _.addIndex(_.reduce(callPermute(''), {})) 
       ) (string.split('')); 
}); 

// getPermutations :: String -> [String] 
var getPermutations = permute('', {}); 
+0

你的問題是什麼?你是否想以無點式的方式編寫'permute'函數?這非常困難。 –

+0

@AaditMShah,這是正確的。我希望能夠以無點式的方式編寫'permute'函數。您的反饋有幫助。我不確定我是否錯過了簡單的東西,錯誤地/次優地看待問題,或者如果遞歸函數本身很難重構爲無點式樣。感謝您的反饋! – Eric

+0

我同意通常不值得重構爲無點,特別是難以實現無點遞歸而不使用定點組合器。但我不同意這個問題應該作爲與無關的鏈接問題的副本來結束,沒有提到一個庫,也沒有談論重構現有代碼,實際上只是與這個共享一個他們都想要JS中的置換函數。這並不會使它們重複。 –

回答

0

似乎有是幾個問題你的解決方案,我怕我沒有時間追逐他們。 (我看到的第一件事情是,你正在使用addIndex不正確。)

但是,如果你想看到Ramda工作permutation功能,I wrote this前一陣子:

// permutations :: [a] -> [[a]] 
const permutations = (tokens, subperms = [[]]) => 
    R.isEmpty(tokens) ? 
    subperms : 
    R.addIndex(R.chain)((token, idx) => permutations(
     R.remove(idx, 1, tokens), 
     R.map(R.append(token), subperms) 
    ), tokens); 

R.map(R.join(''), permutations(['A', 'B', 'C'])); 
//=> ["ABC", "ACB", "BAC", "BCA", "CAB", "CBA"] 

(你可以用這個玩在Ramda REPL。)

+0

您的解決方案不是無點的,如果這是OP想要的。 –

+0

@ScottSauyet,感謝關於'addIndex'的提示。我真的很困惑,爲什麼這不起作用。即使它不是免費的,我真的在挖掘你的解決方案。這聽起來像我可能試圖做一個荒謬的練習,試圖讓它無點。我知道我的重構並不是很接近,但我希望至少在尋求幫助之前展示我的嘗試。大多數遞歸函數固有地難以用無點式編寫,或者僅僅是一些? – Eric

+0

@Eric每個功能都可以轉換爲免費版本。但是,這並不意味着每個功能都應該如此。在[eta轉換](https://en.wikipedia.org/wiki/Lambda_calculus#.CE.B7-轉換)或[函數組合](https://en.wikipedia)等非常有限的情況下,無點函數是有意義的.ORG /維基/ Function_composition)。在大多數其他情況下,有意義的函數更具可讀性。有一個[算法](https://en.wikipedia.org/wiki/Combinatory_logic#Completeness_of_the_S-K_basis)將有意義的表達轉換爲無表情。 –