Как объединить две последовательности на основе первичного ключа? - PullRequest
0 голосов
/ 13 июня 2018

Мне любопытно, как объединить две последовательности в F # на основе первичного ключа.Я ничего не пробовал, потому что понятия не имею, с чего начать.

Пример:

Оригинальные два комплекта:

ID Cash
(1,$5)
(2,$10)
(3,$5)

ID Car
(1,Yes) 
(2,No)
(3,Yes)

Результат:

ID Cash Car
(1,$5,Yes)
(2,$10,No)
(3,$5,Yes)

Ответы [ 2 ]

0 голосов
/ 13 июня 2018

Я, вероятно, использовал бы выражения запроса для решения вашей проблемы.

Учитывая этот набор данных:

let cashList = [ (1, 5); (2, 10); (3, 5) ]
let carList = [ (1, "Yes"); (2, "No"); (3, "Yes") ]

Следующий запрос должен помочь:

let result = query {
  for cash in cashList do
  join car in carList on (fst cash = fst car)
  select (fst cash, snd cash, snd car)
}
0 голосов
/ 13 июня 2018

Вот один из способов сделать это, основываясь на некоторых ваших комментариях.

Это ваши начальные данные, список (int, string) кортежей

let seq1 = [(1,"$5");(2,"$10");(3,"$5")]    
let seq2 = [(1,"Yes");(2,"No");(3,"Yes")]

Мы генерируемуникальные ключи и объединение:

let keys1 = seq1 |> List.map fst |> Set.ofList 
let keys2 = seq2 |> List.map fst |> Set.ofList
let keys3 = keys1 + keys2 

Мы также составляем словарь из двух последовательностей, чтобы упростить поиск:

let map1 = Map.ofList seq1
let map2 = Map.ofList seq2

Наконец, мы проходим все ключи ивытащить соответствующие значения с обеих карт.Чтобы учесть тот факт, что некоторые ключи могут отсутствовать, я использовал TryFind:

keys3
    |> Set.map (fun x -> 
                let val1 = map1.TryFind(x)
                let val2 = map2.TryFind(x)
                (x,val1,val2)
    )

//val it : Set<int * string option * string option> =
//  set [(1, Some "$5", Some "Yes"); (2, Some "$10", Some "No");
//     (3, Some "$5", Some "Yes")]

Теперь вы можете преобразовать этот набор обратно в список или словарь, избавиться от None и т. Д.

...