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

从列表列表中删除元素-haskell,haskell,Haskell,我需要从列表列表中删除存储在[Char]中的元素。让我们有这些元素-“34”和类似的列表-[“2345”,“16”]。我需要做的是从列表列表中删除每个元素。这些元素在这两种情况下都不会出现多次。所以我需要这样的结果-[“25”,“16”]。到目前为止,我已经提出了一个无法正常工作的解决方案: removeFromListOfLists list toRemove = map (\element -> removeFromList list element) toRemove remove

我需要从列表列表中删除存储在
[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”]]

你可以用这个:

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”]

实际上,你要做的是,把整个列表映射,这样你就可以分别得到每个列表。 作为下一步,您可以折叠此特定列表,并检查是否应删除每个项目。

您可以使用此选项:

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”]

实际上,你要做的是,把整个列表映射,这样你就可以分别得到每个列表。
作为下一步,您将折叠此特定列表并检查是否应删除每个项目。

您自上而下组织代码的方式实际上相当不错;您可以使用它来指导您的实现。让我们从以下几点开始:

removeFromListOfLists :: Eq a => [a] -> [[a]] -> [[a]]
removeFromListOfLists toRemove lol = map (\list -> removeFromList toRemove list) lol
(我已经根据您的定义翻转了参数的顺序,因为将您正在处理的列表作为最后一个参数通常更为惯用,以便于组合和部分应用。还要注意,我正在映射列表列表,这可以说是表达此任务的更自然的方式。)

现在我们深入到
removeFromList

removeFromList :: Eq a => [a] -> [a] -> [a]
正如您可能怀疑的那样,它可以用
过滤器
表示:

removeFromList toRemove list = filter (\element -> shouldBeKept element) list
我们仍然需要定义
shouldBeKept
测试。通过使用
(其中
)的本地定义,而不是通过顶级定义,这样做稍微方便一些:

removeFromList :: Eq a => [a] -> [a] -> [a]
removeFromList toRemove list = filter (\element -> shouldBeKept element) list
    where
    shouldBeKept element = element `notElem` toRemove
(这将使用函数。或者,尽管不需要太详细,但您可以定义一个
shouldBeRemoved
测试,然后在调用
过滤器时使用
not(shouldBeRemoved元素)

为了完整性起见,我通常会以一种更无意义的方式来表述这些函数(明智地“省略[ting]参数”,如下所示):


自上而下组织代码的方式实际上相当不错;您可以使用它来指导您的实现。让我们从以下几点开始:

removeFromListOfLists :: Eq a => [a] -> [[a]] -> [[a]]
removeFromListOfLists toRemove lol = map (\list -> removeFromList toRemove list) lol
(我已经根据您的定义翻转了参数的顺序,因为将您正在处理的列表作为最后一个参数通常更为惯用,以便于组合和部分应用。还要注意,我正在映射列表列表,这可以说是表达此任务的更自然的方式。)

现在我们深入到
removeFromList

removeFromList :: Eq a => [a] -> [a] -> [a]
正如您可能怀疑的那样,它可以用
过滤器
表示:

removeFromList toRemove list = filter (\element -> shouldBeKept element) list
我们仍然需要定义
shouldBeKept
测试。通过使用
(其中
)的本地定义,而不是通过顶级定义,这样做稍微方便一些:

removeFromList :: Eq a => [a] -> [a] -> [a]
removeFromList toRemove list = filter (\element -> shouldBeKept element) list
    where
    shouldBeKept element = element `notElem` toRemove
(这将使用函数。或者,尽管不需要太详细,但您可以定义一个
shouldBeRemoved
测试,然后在调用
过滤器时使用
not(shouldBeRemoved元素)

为了完整性起见,我通常会以一种更无意义的方式来表述这些函数(明智地“省略[ting]参数”,如下所示):


如果输入是
[“2435”,“136”]
怎么办。那么输出是不是
[“25”,“16”]
?我说过元素不会出现多次,所以输入永远不会是
[“2435”,“136”]
,这不是真正的问题。更重要的是,您想删除字符串(作为子字符串)还是单个字符?单个字符,因为
'3'
可以出现在第一个列表中,而
'4'
可以出现在另一个列表中如果输入是
[“2435”,“136”]
。那么输出是不是
[“25”,“16”]
?我说过元素不会出现多次,所以输入永远不会是
[“2435”,“136”]
,这不是真正的问题。更重要的是,您想删除字符串(作为子字符串)还是单个字符?单个字符,因为
'3'
可以出现在第一个列表中,而
'4'
可以出现在其他列表中,但我应该向此函数传递哪些参数?我没有看到第二个参数应该是列表列表?在Haskell中,当参数在函数末尾传递时,可以忽略它们。为了避免混淆,我将把它添加到我的答案中。我为您添加了一个简短的版本和一个较长的版本,以查看您的
句柄与原始惯用解决方案
句柄=过滤器(`notElem`items)
(O(m*n^2),m是
项的长度,n是
y
)相比的差异或者高效的解决方案
handle=filter(`S.notMember`S.fromlistitems)
(O((m+n)*log m))。@DanielWagner谢谢,你完全正确。我只是觉得这更容易理解。尽管如此,我还是把它添加到了我的回答中,但是我应该向这个函数传递什么参数呢?我没有看到第二个参数应该是列表列表?在Haskell中,当参数在函数末尾传递时,可以忽略它们。为了避免混淆,我将把它添加到我的答案中。我为您添加了一个简短的版本和一个较长的版本,以查看您的
句柄与原始惯用解决方案
句柄=过滤器(`notElem`items)
(O(m*n^2),m是
项的长度,n是
y
)相比的差异或者高效的解决方案
handle=filter(`S.notMember`S.fromlistitems)
(O((m+n)*log m))。@DanielWagner谢谢,你完全正确。我只是觉得这更容易理解。不过,我补充说