从列表列表中删除元素 - haskell

问题描述 投票:0回答:2

我需要从列表[Char]列表中删除存储在[[Char]]中的元素。让我们有这些元素 - "34"和像这样的列表 - ["2345","16"]。我需要做的是从列表列表中删除每个元素。这些元素中的任何一个都不会多次出现。所以我需要这样的结果 - ["25","16"]。到目前为止,我已经提出了这个无法正常工作的解决方案:

removeFromListOfLists list toRemove = map (\element -> removeFromList list element) toRemove

removeFromList list element = map (\listPart -> remove listPart element) list

remove listPart element = filter (\e -> e/=element) listPart

但我从中得到的是:[["245","16"],["235","16"]]

haskell
2个回答
1
投票

你可以用这个:

import Data.List

removeFromList items list = map handle list where
    handle y = filter (`notElem` items) y

精简版:

removeFromList items = map handle where
    handle = filter (`notElem` items)

示例电话:removeFromList "34" ["2345","16"]

你实际做的是,你映射整个列表,所以你分别得到每个列表。下一步,您将折叠此特定列表并检查每个项目是否应删除。


2
投票

您自上而下组织代码的方式实际上非常好;您可以使用它来指导您的实施。让我们开始:

removeFromListOfLists :: Eq a => [a] -> [[a]] -> [[a]]
removeFromListOfLists toRemove lol = map (\list -> removeFromList toRemove list) lol

(我已经翻了关于你的定义的参数的顺序,因为为了更容易组合和部分应用,将你正在处理的列表作为最后一个参数通常更惯用。还要注意我映射到列表列表,可以说是表达此任务的更自然的方式。)

现在我们深入到removeFromList

removeFromList :: Eq a => [a] -> [a] -> [a]

正如您可能怀疑的那样,它可以用filter表示:

removeFromList toRemove list = filter (\element -> shouldBeKept element) list

我们仍然需要定义shouldBeKept测试。通过使用where的本地定义,而不是通过顶级定义,这样做稍微方便一些:

removeFromList :: Eq a => [a] -> [a] -> [a]
removeFromList toRemove list = filter (\element -> shouldBeKept element) list
    where
    shouldBeKept element = element `notElem` toRemove

(这使用notElem函数。或者,虽然有不必要的详细程度,你可以用shouldBeRemoved定义elem测试,然后在调用not (shouldBeRemoved element)时使用filter。)

为了完整起见,我通常用一种更自由的方式(明智地“省略[ting]参数”,如Stephan Strate put it in a comment)来表达这些函数:

removeFromListOfLists :: Eq a => [a] -> [[a]] -> [[a]]
removeFromListOfLists toRemove = map (removeFromList toRemove)

removeFromList :: Eq a => [a] -> [a] -> [a]
removeFromList toRemove = filter shouldBeKept
    where
    shouldBeKept element = element `notElem` toRemove
© www.soinside.com 2019 - 2024. All rights reserved.