如何在Swift中从数组中删除给定值的元素

78

我想从一个包含x、y和z元素的数组中删除所有值为x的元素

let arr = ['a', 'b', 'c', 'b']

我该如何从arr中删除所有值为'b'的元素?

8个回答

156
一个过滤器:
 let farray = arr.filter {$0 != "b"} 

4
不需要大括号,因为这是一个尾随闭包 :)arr = arr.filter {$0 != 'b'}<3 Swift - sachadso
1
只是指出关于上面的评论,如果没有花括号,编译器确实会抛出“匿名闭包参数未包含在闭包中”的错误。 - geraldWilliam
4
她/他的意思是圆括号,而不是花括号。 - maltalef
2
在 Swift 2 中,您不能使用 ',而需要使用 "。因此,答案将是 let something = arr.filter{$0 != "b"} - Marco Dinatsoli
1
我无法确定即使这个一行代码是否非常易读。 - Jonny
这是最好的答案。 - Mahmud Ahsan

25

如果您需要修改初始数组,则可以使用在Swift 4.2 / Xcode 10中可用的removeAll(where:)函数:

var arr = ["a", "b", "c", "b"]
arr.removeAll(where: { $0 == "b" })
print(arr) // output is ["a", "c"]

然而,如果您正在使用Xcode 9,您可以在Xcode9to10Preparation中找到此函数(该库提供了来自Xcode 10的一些新功能的实现)。


只要类型是可比较的,例如字符串(就像原始问题中一样),这个方法就可以工作。与世界上其他现代语言不同,Swift不提供使用常规值进行此操作的方法。 - user11638666

20
var array : [String]
array = ["one","two","one"]

let itemToRemove = "one"

while array.contains(itemToRemove) {
    if let itemToRemoveIndex = array.index(of: itemToRemove) {
        array.remove(at: itemToRemoveIndex)
    }
}

print(array)

适用于Swift 3.0。


1
虽然这段代码有点凌乱,但它比“filter”解决方案快了大约45%。 - Aaron Brager
@AaronBrager 我刚刚进行了测试,结果比“filter”慢了10%。我想这样比较并没有太多意义,因为结果高度取决于要从源数组中删除的项目有多频繁和分布得有多均匀。 - Eric Aya
@EricD。是的,我同意这取决于源数组(我使用了问题中的数组)。这是我的测试 - filter 从未更快https://gist.github.com/getaaron/11b751b15489b0b95e9e - Aaron Brager
我认为这将取决于您对要删除的值是否存在以及如果您希望在数组中不存在该值时执行某些操作。 - Nitrousjp
不需要使用 containsindex(of:)。只使用 index(of) 会更快,因为它返回一个可选值。 - Leo Dabus
显示剩余2条评论

8

根据评论修改内容:

我喜欢这种方法:

var arr = ["a", "b", "c", "b"]

while let idx = arr.index(of:"b") {
    arr.remove(at: idx)
}

抱歉,我不能直接翻译未提供的内容。请提供需要翻译的文本。
let arr = ['a', 'b', 'c', 'b']

if let idx = arr.index(of:"b") {
    arr.remove(at: idx)
}

2
请注意,这将仅删除第一个等于“b”的数组元素。要删除所有这些元素(如本问题所需),请将if替换为while - Martin R
1
请注意,arr被声明为常量,您不能在其上使用可变方法。 - Leo Dabus
1
顺便提一下,在数组声明中使用的单引号语法是错误的。 - Leo Dabus
马丁和里奥都是对的。感谢指出。我已经编辑了答案。我一定从未尝试过,因为常量声明甚至不应该编译。我的错。 - Jens
1
这种方法要求Array<type>中的类型是可比较的。 - Parker Gibson

3
在Swift 3中,我只需要这样做:
arr = arr.filter { $0 != "a" } 

.filter、.sort 和 .map 可以省时,并且用很少的代码解决很多问题。

这篇文章有很好的示例,解释了它们之间的差异以及它们的工作方式:https://useyourloaf.com/blog/swift-guide-to-map-filter-reduce/


2
如果您需要移除多个元素,感谢最初的回答。
 var mainArray = ["a", "b", "qw", "qe"]
 let thingsToRemoveArray = ["qw", "b"] 


        for k in thingsToRemoveArray {
            mainArray =  mainArray.filter {$0 != k}
          }

1
一般的方法是利用一流过程。(然而,这种方法比你的问题要求的要强大得多。)举个例子,假设你想在许多集合中避免重复使用"Justin"
let avoidJustin = notEqualTester ("Justin")

let arrayOfUsers = // ...

arrayOfUsers.filter (avoidJustin)

let arrayOfFriends = // ...

arrayOfFriends.filter (avoidJustin)

通过这样做,您可以避免每次想要避免 Justin 时都重复创建闭包。以下是 notEqualTester 的示例,它会给定一个 that,返回一个函数,该函数返回 this != that
func notEqualTester<T: Equatable> (that:T) -> ((this:T) -> Bool) {
  return { (this:T) -> Bool in return this != that }
}

this 的返回闭包会捕获 that 的值 - 当 that 不再可用时,这非常有用。


0
如果您只有一个该值的元素,这可能是最简单的方法。
arr.remove(at: arr.index(of: ‘b’))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接