F #: отфильтровывать None и сохранять только некоторые - PullRequest
0 голосов
/ 28 февраля 2019

Быстрый вопрос о том, как эффективно сгруппировать / отфильтровать список / последовательность.

  1. Фильтр только для записей, в которых необязательное поле отсутствует None
  2. Удалите параметр "option" дляупростить будущие процессы (поскольку ни один из них не был отфильтрован)
  3. Группа (я думаю, это не проблема)

Использую ли я лучший подход?

Спасибо!

type tmp = {
    A : string
    B : int option }

type tmp2 = {
    A : string
    B : int }



let inline getOrElse (dft: 'a) (x: 'a option) =
    match x with
    | Some v -> v
    | _      -> dft

let getGrouped (l: tmp list) =
    l |> List.filter  (fun a -> a.B.IsSome)
      |> List.map  (fun a -> {A = a.A ; B = (getOrElse 0 (a.B)) })
      |> List.groupBy (fun a -> a.A)

Ответы [ 2 ]

0 голосов
/ 28 февраля 2019

Наиболее естественный подход для map+filter, когда задействован option, заключается в использовании choose, который объединяет эти две операции и удаляет обертку параметров из отфильтрованного вывода.

Ваш пример будет выглядеть примерно так:

let getGrouped (l: tmp list) =
    l
    |> List.choose (fun a ->
       a.B 
       |> Option.map (fun b -> {A = a.A; B = b})
    |> List.groupBy (fun a -> a.A)
0 голосов
/ 28 февраля 2019

Простое решение - просто использовать свойство, которое позволяет преобразовать опцию в список с одним или нулевым элементом, после чего вы можете определить функцию, например:

let t1 ({A=a; B=b} : tmp) =
        match b with
        | (Some i) -> [{ A = a; B= i}] 
        | _ -> []

let getGrouped (l: tmp list) =
    l |> List.collect t1
      |> List.groupBy (fun a -> a.A)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...