我第二次在不相关的项目中编写以下函数(首先是XML处理,现在自定义命令行标记处理),我感觉它应该存在于某个库中,我只是找不到它。它对列表元素进行分组,每个组从谓词为真的元素开始。
有任何更简单的方法吗?
groupStartBy :: (a -> Bool) -> [a] -> [[a]]
groupStartBy pred xs = reverse $ map reverse $ foldl' step [] xs
where
step as x | pred x = [x]:as
step (a:as) x = (x:a):as
step [] x = [[x]]
答案 0 :(得分:5)
您可以使用groupBy
执行此操作:
import Data.List (groupBy)
groupStartBy :: (a -> Bool) -> [a] -> [[a]]
groupStartBy pred = groupBy (const (not . pred))
-- or in point free style: groupStartBy = groupBy . const . (not .)
答案 1 :(得分:1)
split package在这里非常有用。我没有找到与你的功能具有完全相同功能的东西,但如果你玩一些基本功能,我敢打赌你可以得到你想要的东西。 splitWhen
类似但删除了满足谓词的元素。 split . whenElt
稍近一些,但将谓词元素分成新列表的不同元素。
答案 2 :(得分:0)
也许,比如:
groupStartBy :: (a -> Bool) -> [a] -> [[a]]
groupStartBy f = split (dropInitBlank . keepDelimsL . whenElt $ f)
如果我理解正确的话。 split
,dropInitBlank
,keepDelimsL
和whenElt
来自Data.List.Split。