【问题标题】:Set of keys from a map地图中的一组键
【发布时间】:2013-11-13 17:08:00
【问题描述】:

我有一张地图 X,我正在尝试获取一组满足特定条件的键,如下所示:

Map.Keys X
|> Set.filter (fun x -> ...)

...但我找不到从 F# 的 Map 集合中获取密钥的方法。

【问题讨论】:

    标签: f# hashtable


    【解决方案1】:

    首先将您的map 转换为元组序列(key,value),然后将其映射到仅键的序列:

    map |> Map.toSeq |> Seq.map fst
    

    FSI 样本:

    >Map.ofList[(1,"a");(2,"b")] |> Map.toSeq |> Seq.map fst;;
    val it : seq<int> = seq [1; 2]
    

    或者,由于键的顺序可能无关紧要,您可以使用更急切的方法返回所有键的list。把它做成Microsoft.FSharp.Collections.Map模块的扩展方法keys也不难:

    module Map =
        let keys (m: Map<'Key, 'T>) =
            Map.fold (fun keys key _ -> key::keys) [] m
    

    【讨论】:

    • 结果应该是一个集合而不是一个列表
    • @GuillaumeMassé:作者显然在“...从 F# 的 Map 集合中获取密钥的方式”遇到了麻烦,所以答案解决了这个具体问题。
    • @ympostor 这取决于 (a) 您对效率的定义以及 (b) 在给定的上下文中是否存在对高性能的需求。尽管如此,F# 4.0 Map.filter 更有效地解决了整个原始问题。同样对于我建议的方法,过滤可能会融合到fold,如let filterKeys&lt;'K,'T when 'K: comparison&gt; (p: ('K -&gt; bool)) (m: Map&lt;'K,'T&gt;) = m |&gt; Map.fold (fun ks k _ -&gt; if (p k) then k::ks else ks) []
    【解决方案2】:

    对于一组键,您可以这样做:

    let keys<'k, 'v when 'k : comparison> (map : Map<'k, 'v>) =
        Map.fold (fun s k _ -> Set.add k s) Set.empty map
    

    【讨论】:

      【解决方案3】:

      在 F# 6.0 中,Map 集合现在有一个 Keys property


      老答案

      最易读(并且可能是最有效的,因为不需要先前转换为 Seq 或映射)答案:

      let Keys(map: Map<'K,'V>) =
          seq {
              for KeyValue(key,value) in map do
                  yield key
          } |> Set.ofSeq
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-12-02
        • 1970-01-01
        • 1970-01-01
        • 2017-12-27
        • 1970-01-01
        • 1970-01-01
        • 2021-12-23
        相关资源
        最近更新 更多