Извлечь массив кортежей с разным количеством элементов в F # - PullRequest
2 голосов
/ 06 ноября 2011

У меня есть следующее требование: получить массив кортежей из первого массива согласно внешнему виду элементов во втором массиве:

let totals = [| ("old1", "new1"); ("old2", "new2");  ("old3", "new3"); ("old4", "new4")  |]
let changes = [| "new1"; "new4" |]

Я хочу иметь это:

let updates = [| ("old1", "new1"); ("old4", "new4") |]

Если итоговые значения и изменения обоих массивов имеют одинаковую длину, то я думаю, что это легко:

let updates = Array.zip  changes totals
            |> Array.choose(fun (a, B) -> if a = fst(B) then Some (B) else None)

К сожалению, итоги и изменения имеют разное количество элементов; поэтому я не могу найти простой способ получить нужные мне элементы.

Ответы [ 2 ]

6 голосов
/ 06 ноября 2011

Решение, опубликованное pad , является правильным и будет нормально работать с небольшим количеством элементов в changes.Однако он выполняет итерацию по массиву changes для каждого элемента в total, поэтому он может быть неэффективен для больших массивов.

В качестве альтернативы вы можете превратить changes в тип F # setкоторый позволяет более эффективный тест членства:

// Create set containing 'changes'
let changesSet = Set.ofArray changes

// Filter totals where the second element is in 'changesSet'
totals |> Array.filter (fun (_, v) -> changesSet.Contains(v))

// Same thing using function composition
totals |> Array.filter (snd >> changesSet.Contains)
3 голосов
/ 06 ноября 2011

Вы должны выбрать пары в totals, у которых вторые элементы встречаются в changes:

let updates = 
      totals 
      |> Array.filter (fun (_, x) -> changes |> Array.exists (fun y -> y = x))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...