我想知道是否有一个函数可以让我在第一次出现某个元素时拆分列表,排除该元素。基本上,假设:
listT= [1,3,2,5,6,3,2,6]
然后我想定义(或者不定义,如果它已经存在)一个函数 splitAtFirst 以便
splitAtFirst 2 listT = [[1,3],[5,6,3,2,6]]
到目前为止我的尝试如下:
splitAtfirst::(Eq a)=> a->[a]->[[a]]
splitAtfirst _ []=[]
splitAtfirst a (x:xs)
|a==x = [xs]
|otherwise = [x]: splitAtfirst a (xs)
但是,我明白了
>splitAtfirst 2 [1,3,2,5,6,3,2,6]
>[[1],[3],[5,6,3,2,6]]
我知道为什么会出现这个问题,但到目前为止我还没有找到好的解决方案
感谢任何帮助!
编辑:这是一个辅助函数,只有在检查 elem 是否在列表中后才会被调用,因此处理它不存在的情况并不是真正必要的。感谢您的帮助
最佳答案
由于 dfeuer 已经指出了修复您的实现的方法,我将只提供现成的解决方案:
splitAtFirst :: Eq a => a -> [a] -> ([a], [a])
splitAtFirst x = fmap (drop 1) . break (x ==)
此 splitAtFirst
实现了 dfeuer 答案中三个建议中的第二个选项。关于每个组件的一些注释:
(x ==)
是一个测试与x
是否相等的函数,返回一个Bool
。break
使用 bool 测试(此处为(x ==)
)将列表分成两部分,第二个列表从通过测试的第一个元素开始。这两个列表作为一对返回(请参阅 dfeuer 的答案了解其原因)。drop 1
如果列表中的第一个元素不为空,则将其删除(如果为空,则将其保留)。fmap
需要相当长的时间才能正确解释,所以我只会说fmap f
应用于一对(例如break
) 将函数f
应用于该对的第二个元素。在我们的例子中,fmap (drop 1)
将删除第二个列表的第一个元素——即分隔符。 (要了解有关fmap
的更多信息,请搜索关键字“functor”,或者尝试在列表或Maybe
值上使用它,看看会发生什么。)
关于haskell - 在元素第一次出现时拆分列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40297001/