组合takeWhile,skipWhile

时间:2017-03-22 09:50:34

标签: list f#

在F#中,我发现当我想使用takeWhile时,我通常也想使用skipWhile,即采用满足谓词的列表前缀,并记住其余的列表供后续处理。我不认为有一个标准的库函数同时执行这两个功能,但我可以轻松地编写一个。

我的问题是,这个组合应该叫什么?很明显,它应该有一个标准名称;它是什么?到目前为止,我认为最好的是split,这似乎与splitAt一致。

3 个答案:

答案 0 :(得分:2)

span是我在此功能中看到的另一个名称。例如,in Haskell

答案 1 :(得分:1)

这部分问题对我很突出(强调我的):

  

获取满足谓词的列表前缀,并记住列表的其余部分以进行后续处理

我猜你要用列表的其余部分递归,然后再次应用这个拆分功能。这是我以前想做的几次。最初,我编写了我认为你正在描述的函数但是在更多地考虑之后我意识到可能有更通用的方法来考虑它并完全避免递归,这通常使代码更简单。这是我提出的功能。

module List =
    let groupAdjacentBy f xs =
        let mutable prevKey, i = None, 0
        xs
        |> List.groupBy (fun x ->
            let key = f x
            if prevKey <> Some key then
                i <- i + 1
                prevKey <- Some key
            (i, key))
        |> List.map (fun ((_, k), v) -> (k, v))

let even x = x % 2 = 0
List.groupAdjacentBy even [1; 3; 2; 5; 4; 6]
// [(false, [1; 3]); (true, [2]); (false, [5]); (true, [4; 6])]

我发现这个更容易命名,更有用。也许它适用于您当前的问题。如果您不需要组密钥,则可以通过添加|> List.map snd来删除它们。

尽管我通常避免变异,但在这里使用它允许我使用List.groupBy并避免编写更多代码。

答案 2 :(得分:0)

.slice可以捕获连续范围的意图:

List.slice skipPredicate takePredicate