我是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)
请尝试以下方法
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
使用variant map和filterfunction绝对是一个选择,并且效果很好(这也是学习功能抽象的好方法)。
但是,您也可以使用序列理解,这是一个不错的语法糖,它使编写这类任务更加容易(我认为)。要执行与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并且表达式被括在方括号中的事实使它成为列表理解器。