在Swift 3中从数组中删除对象

时间:2016-11-29 06:22:25

标签: ios arrays swift swift3

在我的应用程序中,我在选择单元格时在数组中添加了一个对象,并在重新选择单元格时取消选择并删除对象。我使用了那段代码但是给了我错误。

extension Array {
    func indexOfObject(object : AnyObject) -> NSInteger {
        return (self as NSArray).indexOfObject(object)
    }

    mutating func removeObject(object : AnyObject) {
        for var index = self.indexOfObject(object); index != NSNotFound; index = self.indexOfObject(object) {
            self.removeAtIndex(index)
        }
    }
}

class MyViewController: UITableViewController {
    var arrContacts: [Any] = []
    var contacts: [Any] = []

    func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
        arrContacts.removeObject(contacts[indexPath.row])
    }
}

它给了我2个错误:

C-style for statement has been removed in Swift 3
Value of type '[Any]' has no member 'removeObject'

13 个答案:

答案 0 :(得分:105)

相当于NSMutableArray' s removeObject的Swift(3)是:

var array = ["alpha", "beta", "gamma"]

if let index = array.index(of:"beta") {
    array.remove(at: index)
}

如果对象是唯一的。根本不需要转换为NSArray并使用indexOfObject:

如果同一对象出现多次,请使用filter。但是,在数据源数组中,索引与特定对象index(of相关联的情况更可取,因为它比filter更快。

<强>更新

在Swift 4.2+中,您可以使用removeAll(where:)删除一次或多次beta次出现:

array.removeAll{$0 == "beta"}

答案 1 :(得分:62)

var a = ["one", "two", "three", "four", "five"]

// Remove/filter item with value 'three'
a = a.filter { $0 != "three" }

答案 2 :(得分:22)

对于Swift 3,您可以使用index(where :)并包含一个闭包,用于比较数组中的对象($ 0)与您要查找的内容。

var array = ["alpha", "beta", "gamma"]
if let index = array.index(where: {$0 == "beta"}) {
  array.remove(at: index)
}

答案 3 :(得分:14)

另一个不错的有用解决方案是创建这种扩展:

extension Array where Element: Equatable {

    @discardableResult mutating func remove(object: Element) -> Bool {
        if let index = index(of: object) {
            self.remove(at: index)
            return true
        }
        return false
    }

    @discardableResult mutating func remove(where predicate: (Array.Iterator.Element) -> Bool) -> Bool {
        if let index = self.index(where: { (element) -> Bool in
            return predicate(element)
        }) {
            self.remove(at: index)
            return true
        }
        return false
    }

}

这样,如果您的数组包含自定义对象:

let obj1 = MyObject(id: 1)
let obj2 = MyObject(id: 2)
var array: [MyObject] = [obj1, obj2]

array.remove(where: { (obj) -> Bool in
    return obj.id == 1
})
// OR
array.remove(object: obj2) 

答案 4 :(得分:5)

  1. for var index = self.indexOfObject(object); index != NSNotFound; index = self.indexOfObject(object)用于C风格的循环,已被删除

  2. 将代码更改为类似的内容,以删除所有类似对象(如果已循环:

    let indexes = arrContacts.enumerated().filter { $0.element == contacts[indexPath.row] }.map{ $0.offset }
    for index in indexes.reversed() {
       arrContacts.remove(at: index)
    }
    

答案 5 :(得分:5)

在Swift 3中,使用以下Extension

extension Array where Element: Equatable{
    mutating func remove (element: Element) {
        if let i = self.index(of: element) {
            self.remove(at: i)
        }
    }
}

示例:

var array = ["alpha", "beta", "gamma"]
array.remove(element: "beta")

答案 6 :(得分:4)

快捷键4

var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]

if let index = students.firstIndex(where: { $0.hasPrefix("A") }) {
   students.remove(at: index)
}

答案 7 :(得分:3)

在Swift 3中从这些对象(名为“array”)的数组中删除唯一对象(名为“objectToRemove”)的正确且有效的单行解决方案是:

if let index = array.enumerated().filter( { $0.element === objectToRemove }).map({ $0.offset }).first {
   array.remove(at: index)
}

答案 8 :(得分:1)

在Swift 3中试试这个

array.remove(at: Index)

而不是

array.removeAtIndex(index)

<强>更新

"Declaration is only valid at file scope".

确保对象在范围内。您可以将范围“内部”设为默认值。

index(of:<Object>)工作,课程应符合Equatable

答案 9 :(得分:0)

扩展数组以轻松实现并允许链接:

.
├── lib
│   └── libfoobar.a
├── src
│   ├── foo
│   │   ├── common.c
│   │   └── foo.c
│   └── bar
│       ├── common.h
│       └── bar.hpp
└── tmp
    ├── foo
    │   ├── common.o
    │   ├── common.s
    │   ├── foo.o
    │   └── foo.s
    └── bar
        ├── common.o
        ├── common.s
        ├── bar.o
        └── bar.s

答案 10 :(得分:0)

快速3和4

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

for (index, element) in array.enumerated().reversed() {
    array.remove(at: index)
}

Swift 4.2 中,您可以使用更高级的方法(速度更快且内存效率更高)

array.removeAll(where: { $0 == "c" })

代替

array = array.filter { !$0.hasPrefix("c") }

了解更多here

答案 11 :(得分:0)

这是找到特定对象索引的官方答案,然后您可以使用该索引轻松删除任何对象:

var students = ["Ben", "Ivy", "Jordell", "Maxime"]
if let i = students.firstIndex(of: "Maxime") {
     // students[i] = "Max"
     students.remove(at: i)
}
print(students)
// Prints ["Ben", "Ivy", "Jordell"]

以下是链接:https://developer.apple.com/documentation/swift/array/2994720-firstindex

答案 12 :(得分:0)

这就是我用过的(Swift 5)...

    extension Array where Element:Equatable
    {
        @discardableResult
        mutating func removeFirst(_ item:Any ) -> Any? {
            for index in 0..<self.count {
                if(item as? Element == self[index]) {
                    return self.remove(at: index)
                }
            }
            return nil
        }
        @discardableResult
        mutating func removeLast(_ item:Any ) -> Any? {
            var index = self.count-1
            while index >= 0 {
                if(item as? Element == self[index]) {
                    return self.remove(at: index)
                }
                index -= 1
            }
            return nil
        }
    }

    var arrContacts:[String] = ["A","B","D","C","B","D"]
    var contacts: [Any] = ["B","D"]
    print(arrContacts)
    var index = 1
    arrContacts.removeFirst(contacts[index])
    print(arrContacts)
    index = 0
    arrContacts.removeLast(contacts[index])
    print(arrContacts)

结果:

   ["A", "B", "D", "C", "B", "D"]
   ["A", "B", "C", "B", "D"]
   ["A", "B", "C", "D"]

重要提示:从中删除项目的数组必须包含Equatable元素(例如对象,字符串,数字等)