Remove elements by index in haskell

后端 未结 8 885

I\'m new in haskell and I\'m looking for some standard functions to work with lists by indexes.

My exact problem is that i want to remove 3 elements after every 5. If i

8条回答
  •  不思量自难忘°
    2021-02-07 23:49

    Two completely different approaches

    1. You can use List.splitAt together with drop:

      import Data.List (splitAt)
      f :: [a] -> [a]
      f [] = []
      f xs = let (h, t) = splitAt 5 xs in h ++ f (drop 3 t)
      

      Now f [1..12] yields [1,2,3,4,5,9,10,11,12]. Note that this function can be expressed more elegantly using uncurry and 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
      

      Since we're using Control.Arrow anyway, we can opt to drop splitAt and instead call in the help of Control.Arrow.(&&&), combined with take:

      import Control.Arrow ((&&&))
      f :: [a] -> [a]
      f [] = []
      f xs = uncurry (++) $ (take 5 &&& (f . drop 8)) xs
      

      But now it's clear that an even shorter solution is the following:

      f :: [a] -> [a] 
      f [] = []
      f xs = take 5 xs ++ (f . drop 8) xs
      

      As Chris Lutz notes, this solution can then be generalized as follows:

      nofm :: Int -> Int -> [a] -> [a]
      nofm _ _ [] = []
      nofm n m xs = take n xs ++ (nofm n m . drop m) xs
      

      Now nofm 5 8 yields the required function. Note that a solution with splitAt may still be more efficient!

    2. Apply some mathematics using map, snd, filter, mod and zip:

      f :: [a] -> [a]
      f = map snd . filter (\(i, _) -> i `mod` 8 < (5 :: Int)) . zip [0..]
      

      The idea here is that we pair each element in the list with its index, a natural number i. We then remove those elements for which i % 8 > 4. The general version of this solution is:

      nofm :: Int -> Int -> [a] -> [a]
      nofm n m = map snd . filter (\(i, _) -> i `mod` m < n) . zip [0..]
      

提交回复
热议问题