web-dev-qa-db-ja.com

Swift 3で配列からオブジェクトを削除する

私のアプリケーションでは、セルを選択するときに1つのオブジェクトを配列に追加し、セルを再選択するときに選択を解除してオブジェクトを削除しました。私はそのコードを使いましたが、エラーを出します。

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'
55

NSMutableArrayremoveObjectと同等のSwift(3)は、

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

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

オブジェクトが一意の場合は。 NSArrayにキャストしてindexOfObject:を使用する必要はまったくありません。

同じオブジェクトが複数回出現する場合はfilterを使用してください。ただし、データソース配列のようにインデックスが特定のオブジェクトに関連付けられている場合は、filterより速いのでindex(ofが適しています。

更新:

Swift 4.2以降では、 removeAll(where:) を使用して、1つまたは複数のbetaを削除できます。

array.removeAll{$0 == "beta"}
108
vadian
var a = ["one", "two", "three", "four", "five"]

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

Swift 3の場合、index(where :)を使用して、配列内のオブジェクト($ 0)を探しているものと比較するクロージャを含めることができます。

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

もう1つの便利で便利な解決策は、この種の拡張機能を作成することです。

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) 
14
Luca Davanzo
  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
Tj3n

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")
5
Mohsenasm

Swift 4

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

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

Swift 3でこれらのオブジェクトの配列( "array"という名前)から一意のオブジェクト( "objectToRemove"という名前)を削除するための正しい方法と実用的な方法は、次のとおりです。

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

Swift 3でこれを試す

array.remove(at: Index)

の代わりに

array.removeAtIndex(index)

更新

"Declaration is only valid at file scope".

オブジェクトが有効範囲内にあることを確認してください。スコープに "internal"を指定できます。これはデフォルトです。

index(of:<Object>)が動作するためには、クラスはEquatableに準拠する必要があります。

1
Dili

配列を簡単にして連鎖できるようにするための拡張:

public extension Array where Element: Equatable {
    @discardableResult
    public mutating func remove(_ item: Element) -> Array {
        if let index = firstIndex(where: { item == $0 }) {
            remove(at: index)
        }
        return self
    }

    @discardableResult
    public mutating func removeAll(_ item: Element) -> Array {
        removeAll(where: { item == $0 })
        return self
    }
}
0
Renetik