2

我正在寻找像 f#'s pick or choose 之类的函数,但它会在其中插入一个累加器。

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

'State 将是累加器。

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

4

1 回答 1

1

这个问题似乎与众所周知的问题很接近,我认为应该以类似的方式解决它,MapGroupReduce步骤分开。

让我们按照您的建议解决将 a 转换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

可以将所有三个步骤包装成一个函数,但我真的认为没有实际理由这样做。

于 2013-08-14T23:09:13.513 回答