我是haskell的新手,我正在寻找一些标准函数来处理索引列表.
我确切的问题是我想在每5个后删除3个元素.如果它不够清楚这里是插图:
OOOOOXXXOOOOOXXX...
Run Code Online (Sandbox Code Playgroud)
我知道如何使用许多参数编写巨大的函数,但有没有聪明的方法来做到这一点?
Ste*_*202 16
您可以List.splitAt与drop:
import Data.List (splitAt)
f :: [a] -> [a]
f [] = []
f xs = let (h, t) = splitAt 5 xs in h ++ f (drop 3 t)
Run Code Online (Sandbox Code Playgroud)
现在f [1..12]收益率[1,2,3,4,5,9,10,11,12].请注意,使用uncurry和可以更优雅地表达此功能Control.Arrow.second:
import Data.List (splitAt)
import Control.Arrow (second)
f :: [a] -> [a]
f [] = []
f xs = uncurry (++) $ second (f . drop 3) $ splitAt 5 xs
Run Code Online (Sandbox Code Playgroud)
既然我们正在使用Control.Arrow,我们可以选择放弃splitAt,而是在帮助下打电话Control.Arrow.(&&&),并结合take:
import Control.Arrow ((&&&))
f :: [a] -> [a]
f [] = []
f xs = uncurry (++) $ (take 5 &&& (f . drop 8)) xs
Run Code Online (Sandbox Code Playgroud)
但现在很明显,更短的解决方案如下:
f :: [a] -> [a]
f [] = []
f xs = take 5 xs ++ (f . drop 8) xs
Run Code Online (Sandbox Code Playgroud)
正如Chris Lutz所说,这个解决方案可以概括如下:
nofm :: Int -> Int -> [a] -> [a]
nofm _ _ [] = []
nofm n m xs = take n xs ++ (nofm n m . drop m) xs
Run Code Online (Sandbox Code Playgroud)
现在nofm 5 8产生所需的功能.请注意,解决方案splitAt可能仍然更有效!
应用数学的一些使用map,snd,filter,mod和zip:
f :: [a] -> [a]
f = map snd . filter (\(i, _) -> i `mod` 8 < (5 :: Int)) . zip [0..]
Run Code Online (Sandbox Code Playgroud)
这里的想法是我们将列表中的每个元素与其索引(自然数i)配对.然后我们删除那些i%8> 4的元素.此解决方案的一般版本是:
nofm :: Int -> Int -> [a] -> [a]
nofm n m = map snd . filter (\(i, _) -> i `mod` m < n) . zip [0..]
Run Code Online (Sandbox Code Playgroud)小智 9
这是我的看法:
deleteAt idx xs = lft ++ rgt
where (lft, (_:rgt)) = splitAt idx xs
Run Code Online (Sandbox Code Playgroud)
您可以轻松计算元素:
strip' (x:xs) n | n == 7 = strip' xs 0
| n >= 5 = strip' xs (n+1)
| n < 5 = x : strip' xs (n+1)
strip l = strip' l 0
Run Code Online (Sandbox Code Playgroud)
尽管开放式编码看起来更短:
strip (a:b:c:d:e:_:_:_:xs) = a:b:c:d:e:strip xs
strip (a:b:c:d:e:xs) = a:b:c:d:e:[]
strip xs = xs
Run Code Online (Sandbox Code Playgroud)
由于没有人制作带有“unfoldr”的版本,这是我的看法:
drop3after5 lst = concat $ unfoldr chunk lst
where
chunk [] = Nothing
chunk lst = Just (take 5 lst, drop (5+3) lst)
Run Code Online (Sandbox Code Playgroud)
貌似是迄今为止最短的