选择累加器

时间:2013-08-14 17:01:20

标签: function collections language-agnostic f#

我正在寻找像f#的选择或选择这样的函数,但是它会在。中填充累加器。

List.choose : ('T -> 'U option) -> 'T list -> 'U list

List.pick : ('T -> 'U option) -> 'T list -> 'U

我想要这个:

List._choose : ('T -> 'State -> ('U option, 'State)) -> 'State -> 'T list -> 'U list

List._pick : ('T -> 'State -> ('U option, 'State)) -> 'State -> 'T list -> 'U

哪里'国家将是累积者。

我正在寻找的答案是这样一个函数的名称,以及函数所在的语言和/或库。

1 个答案:

答案 0 :(得分:1)

这个问题似乎接近于众所周知的问题,我认为应该以类似的方式解决,通过分离 Map 减少步骤

让我们按照您的建议解决将string转换为有序int列表的问题。

let stringToInts (xs:string) =
    /// The Mapper simply maps the character to its numeric value
    let mapper = string >> Int32.Parse

    /// The Grouper "concatenates" 'x' to the 'current' value
    /// if the result is greater than the 'threshold', updates the
    /// 'threshold' and drops the 'current'
    /// otherwise, just updates the 'current'
    let grouper (threshold, current) x =
        let newCurrent = current*10 + x
        if newCurrent > threshold
            then newCurrent, 0
            else threshold, newCurrent

    /// The Reducer takes only the values with zero 'current' field
    /// and unwraps the tuple
    let reducer = function
        | x, 0 -> Some x
        | _    -> None

    xs.ToCharArray()              // get the chars
    |> List.ofArray               // convert to List
    |> List.map mapper            // **Map them to int values
    |> List.scan grouper (97, 0)  // **Group the values so that each one
                                  // is greater than the threshold
    |> List.choose reducer        // **Reduce by zero 'current'
    |> List.tail                  // skip the bootstrapper

"9899100101102103104105"
|> stringToInts
|> List.iter (printf "%O ")
// outputs:
// 98 99 100 101 102 103 104 105

可以将所有三个步骤都包含在一个函数中,但我确实认为没有实际的理由这样做。