从 Haskell 中的列表中删除特定元素
Removing specific elements from lists in Haskell
我很难将 Haskell 和函数式编程放在一起。我想要做的是操纵一个字符串,以便我每次根据给定的数字成为 printing/returning 个特定字符。例如:
printing "testing" 2 = "etn"
printing "testing" 3 = "sn"
我在网上看了很多,据我所知,我可以通过过滤和循环来实现这一点,但我无法get/understand这种语言的语法来获得一个工作程序。
我将尝试描述我的思考过程,以便您了解。此函数符合通过重复函数应用(此处删除一些元素)从输入种子(此处为字符串)创建输出列表(此处为字符串)的模式。因此我选择了 Data.List.unfoldr
.
的实现
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
好的,我需要将种子 b
变成 (Maybe
) 输出 a
和字符串的其余部分。我将调用此子函数 f
并将其传递给 unfoldr
.
printing s n = unfoldr f s
where f b = case drop n b of
[] -> Nothing
(x:xs) -> Just (x,xs)
事实证明,尝试从列表的前面取出头部并返回 Maybe
也是一种常见的模式。是 Data.List.uncons
,所以
printing s n = unfoldr (uncons . drop n) s
很流畅!所以我测试了一下,输出是错误的!您指定的输出实际上例如。 for n=2
选择每第二个字符,即。掉落 (n-1)
个字符。
printing s n = unfoldr (uncons . drop (n-1)) s
我再次测试它,它符合所需的输出。呸!
为了演示 Haskell 语言,一些已接受答案的替代解决方案。
使用列表理解:
printing :: Int -> String -> String
printing j ls = [s | (i, s) <- zip [1 .. ] ls, mod i j == 0]
使用递归:
printing' :: Int -> String -> String
printing' n ls
| null ls' = []
| otherwise = x : printing' n xs
where
ls' = drop (n - 1) ls
(x : xs) = ls'
在这两种情况下,我都翻转了参数,因此更容易进行部分应用:例如,printing 5
是一个新函数,在应用于字符串时会给出每个第 5 个字符。
请注意,稍作修改后它们将适用于任何列表
takeEvery :: Int -> [a] -> [a]
我很难将 Haskell 和函数式编程放在一起。我想要做的是操纵一个字符串,以便我每次根据给定的数字成为 printing/returning 个特定字符。例如:
printing "testing" 2 = "etn"
printing "testing" 3 = "sn"
我在网上看了很多,据我所知,我可以通过过滤和循环来实现这一点,但我无法get/understand这种语言的语法来获得一个工作程序。
我将尝试描述我的思考过程,以便您了解。此函数符合通过重复函数应用(此处删除一些元素)从输入种子(此处为字符串)创建输出列表(此处为字符串)的模式。因此我选择了 Data.List.unfoldr
.
unfoldr :: (b -> Maybe (a, b)) -> b -> [a]
好的,我需要将种子 b
变成 (Maybe
) 输出 a
和字符串的其余部分。我将调用此子函数 f
并将其传递给 unfoldr
.
printing s n = unfoldr f s
where f b = case drop n b of
[] -> Nothing
(x:xs) -> Just (x,xs)
事实证明,尝试从列表的前面取出头部并返回 Maybe
也是一种常见的模式。是 Data.List.uncons
,所以
printing s n = unfoldr (uncons . drop n) s
很流畅!所以我测试了一下,输出是错误的!您指定的输出实际上例如。 for n=2
选择每第二个字符,即。掉落 (n-1)
个字符。
printing s n = unfoldr (uncons . drop (n-1)) s
我再次测试它,它符合所需的输出。呸!
为了演示 Haskell 语言,一些已接受答案的替代解决方案。
使用列表理解:
printing :: Int -> String -> String
printing j ls = [s | (i, s) <- zip [1 .. ] ls, mod i j == 0]
使用递归:
printing' :: Int -> String -> String
printing' n ls
| null ls' = []
| otherwise = x : printing' n xs
where
ls' = drop (n - 1) ls
(x : xs) = ls'
在这两种情况下,我都翻转了参数,因此更容易进行部分应用:例如,printing 5
是一个新函数,在应用于字符串时会给出每个第 5 个字符。
请注意,稍作修改后它们将适用于任何列表
takeEvery :: Int -> [a] -> [a]