我最近需要跨越一个列表,以便只查看一些元素.它有点过滤功能,但并不是那么简单.但首先,这是一个跨越的步伐.
跨越列表 - 或任何可遍历的类型 - 与折叠它相同,但丢弃一些经常遇到的元素(关于步幅值).我们摘掉一个元素,那么下一个值摘掉将成为未来步幅日之一.例如,如果我们跨步一个步幅值设置为0的列表,我们实际上会使列表保持不变.如果我们将1列入一个列表,我们会得到两个元素:
stride 0 [1..10] == [1..10]
stride 1 [1..10] == [1,3,5,7,9]
stride 2 [1..10] == [1,4,7,10]
Run Code Online (Sandbox Code Playgroud)
我看着Data.List,我没有找到任何stride清单.这就是为什么我写了一个功能来跨越我 - 和你的!- 东西:
import Data.DList
-- for Data.List
stride :: (Num a, Eq a) => a -> [b] -> [b]
stride s = toList . snd . foldl (\(sa,xa) x -> if sa == s then (0,xa `snoc` x) else (sa+1,xa)) (s,fromList [])
Run Code Online (Sandbox Code Playgroud)
你可以像上面一样使用它.有可能建议它成为Data.List模块的一部分吗?我认为它可以帮助很多.
一个更简单的实现,也适用于无限列表,效率更高
stride :: Int -> [a] -> [a]
stride s = go
where
go (x:xs) = x : go (drop s xs)
go _ = []
Run Code Online (Sandbox Code Playgroud)
如果你想要它不仅仅是其他类型Int,那就去做吧
import Data.List
stride :: Integral i => i -> [a] -> [a]
stride s = go
where
go (x:xs) = x : go (genericDrop s xs)
go _ = []
Run Code Online (Sandbox Code Playgroud)
对非整数类型这样做是没有意义的IMO.
有可能建议它成为
Data.List模块的一部分吗?
是的,这是可能的,在libraries@haskell.org邮件列表上提出建议.
但是,我不认为它会被接受.实用性太小,无法将其添加到base包中.它会更好地添加到另一个包中.也许将它包括在内split是最好的.