2014-01-10 42 views
9

我是F#的新手,嘗試在F#中重寫我們的應用程序之一,嘗試在此過程中學習它,並且我在列表中遇到了一些問題。我搜索並找到了幾個答案,但我似乎無法讓他們中的任何一個人工作。F#中的列表展平#

我的數據類型,說它是Val regEntries:名單的RegistryKey名單

我想這只是一個列表。

下面是我的代碼:

namespace DataModule 

module RegistryModule = 
    open Microsoft.Win32 

let regEntries = 
    ["SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"; "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"] 
    |> List.map (fun x -> Microsoft.Win32.Registry.LocalMachine.OpenSubKey(x)) 
    |> List.map(fun k -> List.ofArray(k.GetSubKeyNames()) |> List.map (fun x -> k.OpenSubKey(x)) |> List.filter (fun x -> x.GetValue("ProductId") <> null)) 
+0

相關:http://stackoverflow.com/questions/4599657/f-list-selectmany –

回答

7

請嘗試以下

let regEntries = 
    ["SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"; "SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\"] 
    |> Seq.map (fun x -> Microsoft.Win32.Registry.LocalMachine.OpenSubKey(x)) 
    |> Seq.map(fun k -> 
     (k.GetSubKeyNames()) 
     |> Seq.map (fun x -> k.OpenSubKey(x)) 
     |> Seq.filter (fun x -> x.GetValue("ProductId") <> null))) 
    |> Seq.concat 
    |> List.ofSeq 

Seq.concat方法是用於將T list listT list有用。請注意,我將很多List.來電轉接到Seq.來電。目前似乎沒有任何必要創建一個實際list,直到最後一刻,因此我一直是作爲一個簡單的seq

+0

作品像一個魅力非常感謝你。 – twreid

+6

請注意,您可以用單個部分函數Seq.collect f替換管道Seq.map f | Seq.concat',請參見[doc](http://msdn.microsoft.com/zh-cn/ library/vstudio/ee340468%28v = vs.100%29.aspx) – kaefer

+0

不錯!謝謝你的提示。 – twreid

4

使用各種mapfilter功能絕對是一個選項 - 它的偉大工程(它是也是學習功能抽象的好方法)。

但是,您也可以使用序列綜合,這是一種很好的語法糖,可以使寫這些任務變得更容易一些(在我看來)。要做到同樣的事情,什麼是由賈裏德回答情況發生,你可以這樣寫:

let subKeys = 
    [@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\"; //" 
    @"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\"] // " 

let regEntries = 
    [ for subKey in subKeys do  
     let k = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(subKey) 
     for name in k.GetSubKeyNames() do 
     let x = k.OpenSubKey(name) 
     if x.GetValue("ProductId") <> null then 
      yield x ] 

嵌套簡直變成嵌套for環路濾波使用if表達 - 生產序列的新值,你可以使用yield以及表達式被括在方括號中的事實使其成爲列表的理解。

+0

不錯!感謝這與我在C#中所做的更接近。 – twreid