【问题标题】:Extracting Primary Key data value from a dictionary sequence从字典序列中提取主键数据值
【发布时间】:2011-04-11 06:00:47
【问题描述】:

我编写了以下代码来提取字典序列中 ID 字段的值 并将这些作为一组返回 - 基本上我正在寻找 db 表中的行的 PK 值 我曾经填充字典(每个表行 1 个字典)。代码下面是一些示例数据 被加载到字典序列中。

虽然下面的代码有效,但样式可能更实用 - 我不得不求助于 使用可变列表来构建结果集。所以我觉得不合适。

任何人都愿意在这里提供改进的、更实用的解决方案。

// Extract the PK values from a dictionary and create a key set  from these data values
// The expected result here is: set ["PK1"; "PK2"; "PK3"; "PK4"]
let get_keyset (tseq:seq<Dictionary<string,string>>) =  
    let mutable setres =[]  
    for x in tseq do  
        for KeyValue(k,v) in x do  
            // Extract ID values/keys from each dict  
            setres <- x.Item("ID")::setres  
    setres |> List.rev |> Set.ofList   

// Sample Data  
// First Tuple is PK/ID value  
let tabledata = [  
                [("ID", "PK1"); ("a2","aa"); ("a3", "aaa"); ("a4", "aaaa") ]  
                [("ID", "PK2"); ("b2","bb"); ("b3", "bbb"); ("b4", "bbbb") ]  
                [("ID", "PK3"); ("c2","cc"); ("c3", "ccc"); ("c4", "cccc") ]  
                [("ID", "PK4"); ("d2","dd"); ("d3", "ddd"); ("d4", "dddd") ]  
                ]  

//generate dict sequence from datasets  
let gendictseq tabledata =  
    seq {  
        for tl in tabledata do  
            let ddict = new Dictionary<string,string>()    
            for (k,v) in tl do  
                    ddict.Add(k,v)  
            yield ddict  
    }  

【问题讨论】:

  • 如果你使用的是Set.ofList,为什么需要反转列表?

标签: f# dictionary set sequence


【解决方案1】:

您的get_keyset 对我来说看起来很复杂。这要简洁得多:

let get_keyset tseq =
    tseq |> Seq.map (fun (x:Dictionary<_,_>) -> x.["ID"]) |> set

对于gendictseq,我个人更喜欢高阶函数而不是序列表达式,但这主要是个人喜好问题:

let gendictseq tabledata =
    tabledata
    |> Seq.map (fun table ->
        (Dictionary<_,_>(), table)
        ||> List.fold (fun dict keyValue -> dict.Add keyValue; dict))

【讨论】:

  • 同意我的代码中的卷积 - 这就是我发布的原因。您的解决方案说明了 fp 方法的真正威力,其中代码可以真正压缩成几个简洁的表达式。 (我还在学习这些东西——你的例子真的很有帮助——谢谢)。
  • @BrendanC : get_keyset 的另一种有趣的写法是:let get_keyset : Dictionary&lt;_,string&gt; seq -&gt; Set&lt;_&gt; = Seq.map (fun x -&gt; x.["ID"]) &gt;&gt; set :-]
【解决方案2】:

使用ResizeArray(C# 中的List&lt;T&gt;)比可变列表变量更好:

let getKeyset (tseq:seq<Dictionary<string,string>>) =  
    let setres = new ResizeArray<string>()
    for x in tseq do 
        for KeyValue(k,v) in x do 
            setres.Add(x.["ID"])
    setres |> Set.ofSeq

或使用功能更强大的序列计算:

let getKeyset2 (tseq:seq<Dictionary<string,string>>) =  
    seq {
        for x in tseq do 
            for KeyValue(k,v) in x do 
                yield x.["ID"]
        }
    |> Set.ofSeq

【讨论】:

  • 我认为序列表达式较少功能性更强...
【解决方案3】:

这个操作在功能上是如下图所示:

let get_keyset_new (tseq:seq<Dictionary<string,string>>) = 
  let s = tseq |> Seq.map (fun i -> i |> Seq.map (fun e -> i.Item("ID") ) )
  seq {
      for i in s do
          yield! i
  } |> Set.ofSeq

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-01-31
    • 2021-09-26
    • 1970-01-01
    • 1970-01-01
    • 2013-06-09
    • 2021-09-17
    • 1970-01-01
    • 2021-02-12
    相关资源
    最近更新 更多