F#中的列表展平

twr*_*eid 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))
Run Code Online (Sandbox Code Playgroud)

Jar*_*Par 9

请尝试以下方法

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
Run Code Online (Sandbox Code Playgroud)

Seq.concat方法可用于将a转换T list list为a T list.请注意,我将大量List.呼叫切换为Seq.呼叫.似乎没有任何需要创建一个实际list直到最后因此我保持它简单seq

  • 请注意,您可以使用单个部分函数`Seq.collect f`替换管道`Seq.map f |> Seq.concat`,请参阅[doc](http://msdn.microsoft.com/en-us/library /vstudio/ee340468%28v=vs.100%29.aspx) (6认同)
  • 你也可以用`Seq.map k.OpenSubKey`替换'Seq.map(fun x - > k.OpenSubKey(x))`.同样,对于另一个对OpenSubKey的调用. (2认同)

Tom*_*cek 5

使用variant mapfilterfunction绝对是一个选择,并且效果很好(这也是学习功能抽象的好方法)。

但是,您也可以使用序列理解,这是一个不错的语法糖,它使编写这类任务更加容易(我认为)。要执行与Jared的答案相同的操作,您可以编写:

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 ]
Run Code Online (Sandbox Code Playgroud)

嵌套简单地变成了嵌套for循环,并使用if- 表示过滤,以生成可以使用的序列的新值,yield并且表达式被括在方括号中的事实使它成为列表理解器。