私のアプリケーションでは、セルを選択するときに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'
NSMutableArray
のremoveObject
と同等の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"}
var a = ["one", "two", "three", "four", "five"]
// Remove/filter item with value 'three'
a = a.filter { $0 != "three" }
Swift 3の場合、index(where :)を使用して、配列内のオブジェクト($ 0)を探しているものと比較するクロージャを含めることができます。
var array = ["alpha", "beta", "gamma"]
if let index = array.index(where: {$0 == "beta"}) {
array.remove(at: index)
}
もう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)
for var index = self.indexOfObject(object); index != NSNotFound; index = self.indexOfObject(object)
はCスタイルのループ用で、削除されました
ループしている場合は、類似のオブジェクトをすべて削除するために、コードを次のようなコードに変更します。
let indexes = arrContacts.enumerated().filter { $0.element == contacts[indexPath.row] }.map{ $0.offset }
for index in indexes.reversed() {
arrContacts.remove(at: index)
}
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")
Swift 4
var students = ["Kofi", "Abena", "Peter", "Kweku", "Akosua"]
if let index = students.firstIndex(where: { $0.hasPrefix("A") }) {
students.remove(at: index)
}
Swift 3でこれらのオブジェクトの配列( "array"という名前)から一意のオブジェクト( "objectToRemove"という名前)を削除するための正しい方法と実用的な方法は、次のとおりです。
if let index = array.enumerated().filter( { $0.element === objectToRemove }).map({ $0.offset }).first {
array.remove(at: index)
}
Swift 3でこれを試す
array.remove(at: Index)
の代わりに
array.removeAtIndex(index)
更新
"Declaration is only valid at file scope".
オブジェクトが有効範囲内にあることを確認してください。スコープに "internal"を指定できます。これはデフォルトです。
index(of:<Object>)
が動作するためには、クラスはEquatable
に準拠する必要があります。
配列を簡単にして連鎖できるようにするための拡張:
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
}
}