gpt4 book ai didi

list - 在haskell中按索引删除元素

转载 作者:行者123 更新时间:2023-12-04 01:18:59 24 4
gpt4 key购买 nike

我是haskell 的新手,我正在寻找一些标准函数来处理索引列表。

我的确切问题是我想在每 5 个元素之后删除 3 个元素。如果它不够清楚,这里是插图:

OOOOOXXXOOOOOXXX...

我知道如何编写带有许多参数的巨大函数,但是有什么聪明的方法可以做到这一点吗?

最佳答案

两种完全不同的方法

  • 您可以使用 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)

    现在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

    由于我们使用 Control.Arrow 无论如何,我们可以选择放弃 splitAt而是求助于 Control.Arrow.(&&&) , 结合 take :
    import Control.Arrow ((&&&))
    f :: [a] -> [a]
    f [] = []
    f xs = uncurry (++) $ (take 5 &&& (f . drop 8)) xs

    但现在很明显,一个更短的解决方案如下:
    f :: [a] -> [a] 
    f [] = []
    f xs = take 5 xs ++ (f . drop 8) xs

    Chris Lutz注意,这个解决方案可以概括如下:
    nofm :: Int -> Int -> [a] -> [a]
    nofm _ _ [] = []
    nofm n m xs = take n xs ++ (nofm n m . drop m) xs

    现在nofm 5 8产生所需的功能。请注意,splitAt 的解决方案可能还是更有效率!
  • 使用 map 应用一些数学, snd , filter , mod zip :
    f :: [a] -> [a]
    f = map snd . filter (\(i, _) -> i `mod` 8 < (5 :: Int)) . zip [0..]

    这里的想法是我们将列表中的每个元素与其索引配对,一个自然数 i。然后我们删除那些 i % 8 > 4 的元素。这个解决方案的一般版本是:
    nofm :: Int -> Int -> [a] -> [a]
    nofm n m = map snd . filter (\(i, _) -> i `mod` m < n) . zip [0..]
  • 关于list - 在haskell中按索引删除元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1736028/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com