list - 在 Haskell 中取出列表中某个元素的最后一次出现

标签 list haskell recursion

我在编写这个接受谓词和整数列表的函数时遇到问题,然后消除列表中最后一次出现的满足谓词的整数。我能够使用下面的函数取出列表中第一次出现的谓词:

fun :: (Int -> Bool) -> [Int] -> [Int]
fun check (s:ss)
 |check s = ss
 |otherwise = s : fun check ss

我需要帮助的是我应该如何修改此函数以取出最后一次出现的整数,而不是第一次出现的整数。例如,fun (<2) [3,4,1,5,0,-3,9]会返回 [3,4,1,5,0,9] .

最佳答案

(由于某些缩进问题,我无法使用 where)

removeLast :: (a -> Bool) -> [a] -> [a]
removeLast p xs =
    let
        go c  []    = tail (c [])
        go c (x:xs)
            | p x       = c (go (x:) xs)
            | otherwise = go (c . (x:)) xs
    in case break p xs of
        (ok, [])   -> ok
        (ok, x:xs) -> ok ++ go (x:) xs

go 收集谓词不包含在差异列表中的元素,并在找到满足谓词的新元素后将此列表添加到结果中。 break p xs 上的模式匹配可确保差异列表始终以满足谓词的元素开头,如果它是最后一个,我们可以将其删除。

适用于无限列表:

main = do
    print $ removeLast (< 2) [3,4,1,5,0,-3,9]        -- [3,4,1,5,0,9]
    print $ removeLast (== 2) [1,3]                  -- [1,3]
    print $ take 10 $ removeLast (< 2) (cycle [1,3]) -- [1,3,1,3,1,3,1,3,1,3]

这是一个混淆版本:

removeLast :: (a -> Bool) -> [a] -> [a]
removeLast p xs = case break p xs of
    (ok, [])   -> ok
    (ok, x:xs) -> ok ++ foldr step (tail . ($[])) xs (x:) where
        step x r c = if p x then c (r (x:)) else r (c . (x:))

关于list - 在 Haskell 中取出列表中某个元素的最后一次出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33685051/

相关文章:

r - 将数据框添加为列表元素(用于循环)

haskell - Cabal:阻止安装基础包

ruby - 算法:在给定单词列表的情况下解决填字游戏

c# - 从列表中删除随机项目 C#

Java:迭代器/可迭代器的 Collections.list

scala - 如何在 Scala 中组合柯里化(Currying)函数

haskell - 使用 Int 类型与积分约束。优势?

javascript - 如何将 **嵌套** 对象作为 JSON 从后端的 Ruby 获取到前端的 AJAX

java - 对前 n 个倒数求和的递归函数

python - 交互链表时打印 None 而不是什么也不打印