gpt4 book ai didi

list - 如果元素存在则删除元素但添加它的函数不存在

转载 作者:行者123 更新时间:2023-12-01 07:55:05 25 4
gpt4 key购买 nike

我正在寻找一种更简洁的方法来编写一个函数,如果列表不包含元素,则将元素添加到列表中。或者如果列表确实包含它,则以其他方式删除它,我现在正在使用 if 子句并且该函数正在运行。

但我正试图找到一种更 haskell-ish 的方法来解决这个问题。

这是我的代码:

removeElemOrAdd :: Eq a => a -> [a] -> [a]
removeElemOrAdd elem list = if (List.elem elem list)
then (filter(\x -> x /= elem) list)
else (elem:list)

最佳答案

注意:您的问题中的一个小歧义是当 x 在原始列表中已经出现 多次 时该怎么做。我假设这不会发生,如果发生,只会删除第一次。这意味着 removeElemOrAdd 2 [4,2,5,2,7] 将导致 [4,5,2,7]。此外,未指定应在何处添加该项目。因为它有一些优势,所以我选择在列表末尾这样做。

不使用任何库方法的实现如下:

removeElemOrAdd :: Eq a => a -> [a] -> [a]
removeElemOrAdd x (y:ys) | x == y = ys
| otherwise = y : removeElemOrAdd x ys
removeElemOrAdd x _ = [x]

或更短的版本:

removeElemOrAdd :: Eq a => a -> [a] -> [a]
removeElemOrAdd x = reoa
where reoa (y:ys) | x == y = ys
| otherwise = y : reoa ys
reoa _ = [x]

或等效的实现(见下面的讨论):

removeElemOrAdd :: Eq a => a -> [a] -> [a]
removeElemOrAdd x = reoa
where reoa (y:ys) | x == y = ys
| otherwise = y : reoa ys
reoa [] = [x]

该函数的工作原理如下:如果我们讨论的列表至少包含一项 (y:ys),我们将 xy 进行比较,如果它们相等,我们返回 ys:在这种情况下,我们已经删除了元素,我们就完成了。

现在,如果两者不相等,我们返回一个列表构造 (:),头部为 y,因为我们需要保留 y 并在尾部,我们将使用 xys 进行递归调用 removeElemOrAdd。的确:有可能是尾部ys的某处有一个x要去掉,而且我们还需要把x加到列表中如果它没有发生。

该子句将在列表中递归循环。从它找到满足 x == yy 的那一刻起,它就会删除那个 y。然而,我们有可能到达列表的末尾,但仍未找到该元素。在这种情况下,我们将调用最终条款。这里我们知道列表是空的(我们可以编写 removeElemOrAdd x [])但是为了使函数定义在语法上完整,我选择使用下划线。只有在列表中找不到 x 时,我们才能达到此状态,因此我们通过返回 [x] 将其添加到列表的尾部。

与使用 if-then-else 相比,这种方法的一个优点是它可以同时完成所有任务(检查、删除和添加),从而提高效率。

另一个优点是它可以在“无限”列表(例如素数列表)上运行。列表是惰性求值的,所以如果你想取前三项,这个函数只会检查前三项是否相等。

关于list - 如果元素存在则删除元素但添加它的函数不存在,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34069510/

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