在Swift中枚举期间从数组中删除?

时间:2015-02-04 14:28:45

标签: ios arrays swift enumeration

我想通过Swift中的数组进行枚举,并删除某些项目。我想知道这是否安全,如果没有,我应该如何做到这一点。

目前,我会这样做:

for (index, aString: String) in enumerate(array) {
    //Some of the strings...
    array.removeAtIndex(index)
}

9 个答案:

答案 0 :(得分:58)

在Swift 2中,使用enumeratereverse非常容易。

var a = [1,2,3,4,5,6]
for (i,num) in a.enumerate().reverse() {
    a.removeAtIndex(i)
}
print(a)

在这里查看我的swiftstub: http://swiftstub.com/944024718/?v=beta

答案 1 :(得分:52)

您可以考虑filter方式:

var theStrings = ["foo", "bar", "zxy"]

// Filter only strings that begins with "b"
theStrings = theStrings.filter { $0.hasPrefix("b") }

filter的参数只是一个闭包,它接受一个数组类型实例(在本例中为String)并返回Bool。当结果为true时,它会保留元素,否则元素将被过滤掉。

答案 2 :(得分:27)

Swift 3和4 中,这将是:

根据约翰斯顿的回答,有了数字,

var a = [1,2,3,4,5,6]
for (i,num) in a.enumerated().reversed() {
   a.remove(at: i)
}
print(a)

字符串作为OP的问题:

var b = ["a", "b", "c", "d", "e", "f"]

for (i,str) in b.enumerated().reversed()
{
    if str == "c"
    {
        b.remove(at: i)
    }
}
print(b)

但是,现在在Swift 4.2中,Apple甚至在WWDC2018中推荐了更好,更快的方式

var c = ["a", "b", "c", "d", "e", "f"]
c.removeAll(where: {$0 == "c"})
print(c)

这种新方式有几个优点:

  1. 比使用filter的实施更快。
  2. 它不需要反转阵列。
  3. 它会就地删除项目,因此它会更新原始数组,而不是分配和返回一个新数组。

答案 3 :(得分:12)

当从数组中删除某个索引处的元素时,所有后续元素的位置(和索引)都会更改,因为它们会向后移动一个位置。

所以最好的方法是以相反的顺序导航数组 - 在这种情况下,我建议使用传统的for循环:

for var index = array.count - 1; index >= 0; --index {
    if condition {
        array.removeAtIndex(index)
    }
}

但是在我看来,最好的方法是使用filter方法,如@perlfly在他的回答中所述。

答案 4 :(得分:4)

没有在安装过程中改变数组是不安全的,你的代码会崩溃。

如果您只想删除少数几个对象,可以使用filter功能。

答案 5 :(得分:2)

创建一个可变数组来存储要删除的项目,然后在枚举后从原始项目中删除这些项目。或者,创建数组的副本(不可变),枚举该数组并在枚举时从原始数据中删除对象(而不是索引)。

答案 6 :(得分:1)

我建议在枚举期间将元素设置为nil,并在完成后使用arrays filter()方法删除所有空元素。

答案 7 :(得分:0)

传统的for循环可以替换为简单的while循环,如果在删除之前还需要对每个元素执行一些其他操作,则很有用。

var index = array.count-1
while index >= 0 {

     let element = array[index]
     //any operations on element
     array.remove(at: index)

     index -= 1
}

答案 8 :(得分:0)

只需添加一下,如果您有多个数组,并且数组A的索引N中的每个元素都与数组B的索引N相关,那么您仍然可以使用反转枚举数组的方法(就像过去的答案一样)。但是请记住,在访问和删除其他数组的元素时,无需反转它们。

Like so, (one can copy and paste this on Playground)

var a = ["a", "b", "c", "d"]
var b = [1, 2, 3, 4]
var c = ["!", "@", "#", "$"]

// remove c, 3, #

for (index, ch) in a.enumerated().reversed() {
    print("CH: \(ch). INDEX: \(index) | b: \(b[index]) | c: \(c[index])")
    if ch == "c" {
        a.remove(at: index)
        b.remove(at: index)
        c.remove(at: index)
    }
}

print("-----")
print(a) // ["a", "b", "d"]
print(b) // [1, 2, 4]
print(c) // ["!", "@", "$"]