我想创建一个像List.find这样的F#函数,但是我想搜索字典中的任何键并返回相应的字典值,而不是搜索单个值。 例如,这是我正在尝试做的(差)实现。
let dict1=dict[(1,"A");(2,"B");(3,"C");(4,"D");(5,"E");(6,"F")]
let findInDict l =
let mutable found=false
let mutable value=""
for elem in l do
let f,v=dict1.TryGetValue(elem)
value<-if f && not found then v else value
found<-if not found then f else found
value
findInDict [9;2;5]
>
val dict1 : System.Collections.Generic.IDictionary<int,string>
val findInDict : l:seq<int> -> string
val it : string = "B"
什么是功能等同物?
答案 0 :(得分:2)
这个功能几乎感觉有点矫枉过正。您可以使用列表解析在一行中执行此操作:
[for x in [9;4;5] do if dict1.ContainsKey x then yield dict1.[x]]
编辑:
重新阅读你的问题之后,我意识到上面的内容并不是你想要的。
let rec findAValue l =
match l with
| [] -> None
| x::xs -> if dict1.ContainsKey x then Some(dict1.[x]) else findAValue xs
或更简洁:
let rec findAValue = function
| [] -> None
| x::xs -> if dict1.ContainsKey x then Some(dict1.[x]) else findAValue xs
更简洁:
let findAValue = List.tryPick (fun x-> if dict1.ContainsKey x then Some(dict1.[x]) else None)
let highPerformanceFindAValue = List.tryPick (fun x-> match dict1.TryGetValue x with
| true, value->Some(value)
| _ -> None)
如果未找到任何值,则结果为None
,否则为Some(value)
。
答案 1 :(得分:0)
let findFirst l (dict: System.Collections.Generic.Dictionary<int, string>) =
let o = l |> List.tryFind (fun i -> dict.ContainsKey(i)) |> Option.map (fun k -> dict.[k])
match o with | None -> "" | Some(k) -> k
答案 2 :(得分:0)
有很多方法可以做到这一点。
显而易见的解决方案是迭代,就像你一样:
let findInDict (d:IDictionary<'a, 'b>) l =
seq {
for key in l do
let f, v = d.TryGetValue(key)
if f then yield v
}
这是好的,我想。它或多或少地模仿了典型的逐步方法。
你可以用一些序列运算符重写这个:
let findInDict1 (d:IDictionary<'a, 'b>) l =
Seq.filter (fun elem -> d.ContainsKey(elem)) l |> Seq.map (fun elem -> d.Item(elem))
感觉功能更强,但显然正在做更多的工作。
let findInDict2 (d:IDictionary<'a, 'b>) l =
Seq.choose(fun elem ->
let f,v = d.TryGetValue(elem)
if f then Some(v) else None) l
最后一个是最有意义的,因为我们每个键只能访问一次字典,并且选择将为我们完成所有繁重的工作。