Dot-Net

兩個列表的叉積

  • March 2, 2021

搞亂 List 模組的“擴展功能”。(我花了很長時間開發“mapfold”——它執行緒化了一個像 fold 這樣的累加器,但使用它作為參數來創建像 map 這樣的新值——然後發現這就是List.scan_left它的作用)

為了生成測試數據,我需要做兩個列表的叉積,這就是我想出的:

///Perform cross product of two lists, return tuple
let crossproduct l1 l2 =
   let product lst v2 = List.map (fun v1 -> (v1, v2)) lst
   List.map_concat (product l1) l2

這有什麼好處,還是已經有更好的方法來做到這一點?

同樣的問題:

///Perform cross product of three lists, return tuple
let crossproduct3 l1 l2 l3 =
   let tuplelist = crossproduct l1 l2 //not sure this is the best way...
   let product3 lst2 v3 = List.map (fun (v1, v2) -> (v1, v2, v3)) lst2
   List.map_concat (product3 tuplelist) l3

另一種選擇是使用 F#“序列表達式”並編寫如下內容:

let crossproduct l1 l2 =
 seq { for el1 in l1 do
         for el2 in l2 do
           yield el1, el2 };;

(其實和你寫的差不多,因為’for .. in .. do’在序列表達式中可以看成map_concat)。這適用於(惰性)序列,但如果你想使用列表,你只需將程式碼包裝在裡面

而不是在 seq { … } 內。

從 F# 4.0 開始,您可以使用List.allPairs給出兩個列表的笛卡爾積。

如果您有兩個以上的列表,請參閱如何在 F# 中計算 n 個序列的笛卡爾積?

引用自:https://stackoverflow.com/questions/482866