F#和Series,如何写一个Series.choose?

F# and Series, How to write a Series.choose?

我决定写一个 Series.choose 函数,类似于我们在 Seq 上的函数,我想知道你是否认为这是最好的写法,回到 Seq 那里是那里的一个功能。

let choose (f: 'K * 'V -> ('K * 'U) option) (e : Series<'K,'V>) =
        e |> Series.map (fun k v -> k, v)
          |> Series.values
          |> (Seq.choose f)
          |> Series.ofValues
          |> Series.map (fun _ v -> snd v)
          |> Series.indexWith (e |> Series.keys)

谢谢

mapAll 几乎就是您所需要的,它只是签名略有不同(特别是,不能更改密钥)。如果您确实需要更改密钥,它会变得更加困难,但仍然不需要通过 Seq。它还取决于您希望如何处理 e.

中的缺失值

未测试(因为我这里没有Visual Studio),假设e没有缺失值,但应该给出思路:

let choose (f: 'K * 'V -> ('K * 'U) option) (e : Series<'K,'V>) =
    e |> Series.mapAll (fun k (Some v) -> f (k, v)) // Series<'K, ('K, 'U)> 
      |> Series.dropMissing // drops cases where f returned None
      |> fun e1 -> e1.SelectKeys (fun kvp -> fst kvp.Value.Value) // changes the keys to the ones f returned
      |> Series.mapValues snd // removes the keys from the values

这是我为 "Toolbox" 写的。以防将来为某人节省时间...

    /// Choose only on values keeping the same keys
    let chooseV (f: 'V -> 'U option) (e : Series<'K,'V>) =
        e |> Series.mapAll (fun _ (Some v) -> f v)
          |> Series.dropMissing

    /// Choose on both keys and values, changing the keys to type 'J
    let chooseKV (f: 'K * 'V -> ('J * 'U) option) (e : Series<'K,'V>) =
        e |> Series.mapAll (fun k (Some v) -> f (k, v))
          |> Series.dropMissing
          |> fun e1 -> e1.SelectKeys (fun kvp -> fst kvp.Value.Value)
          |> Series.mapValues snd

    /// Choose on just the values using the keys in the function
    let choose (f: 'K * 'V -> ('K * 'U) option) (e : Series<'K,'V>) =
        e |> Series.mapAll (fun k (Some v) -> f (k, v))
          |> Series.dropMissing
          |> Series.mapValues snd