例如,我需要一个功能:
gather :: Int -> [a] -> [[a]]
gather n list = ???
Run Code Online (Sandbox Code Playgroud)
哪里gather 3 "Hello!" == ["Hel","ell","llo","ol!"].
我有一个有效的实施:
gather :: Int-> [a] -> [[a]]
gather n list =
unfoldr
(\x ->
if fst x + n > length (snd x) then
Nothing
else
Just
(take
n
(drop
(fst x)
(snd x)),
(fst x + 1, snd x)))
(0, list)
Run Code Online (Sandbox Code Playgroud)
但是我想知道这种语言中是否已经内置了一些内容?我扫描了Data.List但没有看到任何内容.
Lee*_*Lee 14
你可以使用tails:
gather n l = filter ((== n) . length) $ map (take n) $ tails l
Run Code Online (Sandbox Code Playgroud)
或使用takeWhile而不是filter:
gather n l = takeWhile ((== n) . length) $ map (take n) $ tails l
Run Code Online (Sandbox Code Playgroud)
编辑:您可以通过删除评论中建议的n返回列表的最后元素来删除过滤器步骤tails:
gather n = map (take n) . dropLast n . tails
where dropLast n xs = zipWith const xs (drop n xs)
Run Code Online (Sandbox Code Playgroud)
由于拉链的特性,可以自动安排尾部掉落,
import Data.List (tails)
g :: Int -> [a] -> [[a]]
g n = foldr (zipWith (:)) (repeat []) . take n . tails
Run Code Online (Sandbox Code Playgroud)
或者简单transpose . take n . tails就足够了.测试:
Prelude Data.List> g 3 [1..10]
[[1,2,3],[2,3,4],[3,4,5],[4,5,6],[5,6] ,7],[6,7,8],[7,8,9],[8,9,10]]
Prelude Data.List> transpose.拿3.尾巴$ [1..10]
[[1,2,3],[2,3,4],[3,4,5],[4,5,6],[5,6,7],[ 6,7,8],[7,8,9],[8,9,10],[9,10],[10]]
(编辑2018-09-16 :)使用压缩可以在更高的层次上表达,具有traverse ZipList:
g :: Int -> [a] -> [[a]]
g n = getZipList . traverse ZipList . take n . tails
Run Code Online (Sandbox Code Playgroud)