从字典序列中提取主键数据值

时间:2011-04-11 06:00:48

标签: f# dictionary set sequence

我编写了以下代码来提取字典序列中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  
    }  

3 个答案:

答案 0 :(得分:3)

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))

答案 1 :(得分:1)

使用ResizeArray(C#中的List<T>)比可变列表变量更好:

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

答案 2 :(得分:0)

从功能上讲,此操作的地图如下所示:

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