Извлечение значения данных первичного ключа из словарной последовательности - PullRequest
1 голос
/ 11 апреля 2011

Я написал следующий код, чтобы извлечь значения полей ID в последовательности словарей и вернуть их в виде набора - в основном я ищу значения 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 ]

3 голосов
/ 11 апреля 2011

Ваш 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 голос
/ 11 апреля 2011

Использование ResizeArray (List<T> в C #) лучше, чем переменная изменяемого списка:

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
0 голосов
/ 11 апреля 2011

Функционально эта операция является картой, как показано ниже:

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