[ios] Removing object from array in Swift 3

In my application I added one object in array when select cell and unselect and remove object when re-select cell. I used that code but give me error.

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])
    }
}

It gives me 2 error like that:

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

This question is related to ios arrays swift swift3

The answer is


This is what I've used (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)

Results:

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

Important: The array from which you remove items must contain Equatable elements (such as objects, strings, number, etc.)


The correct and working one-line solution for deleting a unique object (named "objectToRemove") from an array of these objects (named "array") in Swift 3 is:

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

This is official answer to find index of specific object, then you can easily remove any object using that index :

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"]

Here is the link: https://developer.apple.com/documentation/swift/array/2994720-firstindex


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

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

In Swift 5, Use this Extension:

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

example:

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

In Swift 3, Use this Extension:

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

example:

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

Another nice and useful solution is to create this kind of extension:

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
    }

}

In this way, if you have your array with custom objects:

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 Swift 3, you can use index(where:) and include a closure that does the comparison of an object in the array ($0) with whatever you are looking for.

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

Extension for array to do it easily and allow chaining for Swift 4.2 and up:

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
    }
}

Swift 4

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

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

  1. for var index = self.indexOfObject(object); index != NSNotFound; index = self.indexOfObject(object) is for loop in C-style and has been removed

  2. Change your code to something like this to remove all similar object if it have looped:

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

In Swift 3 and 4

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

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

From Swift 4.2 you can use more advanced approach(faster and memory efficient)

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

instead of

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

Read more here


Try this in Swift 3

array.remove(at: Index)

Instead of

array.removeAtIndex(index)

Update

"Declaration is only valid at file scope".

Make sure the object is in scope. You can give scope "internal", which is default.

index(of:<Object>) to work, class should conform to Equatable


Examples related to ios

Adding a UISegmentedControl to UITableView Crop image to specified size and picture location Undefined Symbols error when integrating Apptentive iOS SDK via Cocoapods Keep placeholder text in UITextField on input in IOS Accessing AppDelegate from framework? Autoresize View When SubViews are Added Warp \ bend effect on a UIView? Speech input for visually impaired users without the need to tap the screen make UITableViewCell selectable only while editing Xcode 12, building for iOS Simulator, but linking in object file built for iOS, for architecture arm64

Examples related to arrays

PHP array value passes to next row Use NSInteger as array index How do I show a message in the foreach loop? Objects are not valid as a React child. If you meant to render a collection of children, use an array instead Iterating over arrays in Python 3 Best way to "push" into C# array Sort Array of object by object field in Angular 6 Checking for duplicate strings in JavaScript array what does numpy ndarray shape do? How to round a numpy array?

Examples related to swift

Make a VStack fill the width of the screen in SwiftUI Xcode 10.2.1 Command PhaseScriptExecution failed with a nonzero exit code Command CompileSwift failed with a nonzero exit code in Xcode 10 Convert Json string to Json object in Swift 4 iOS Swift - Get the Current Local Time and Date Timestamp Xcode 9 Swift Language Version (SWIFT_VERSION) How do I use Safe Area Layout programmatically? How can I use String substring in Swift 4? 'substring(to:)' is deprecated: Please use String slicing subscript with a 'partial range from' operator Safe Area of Xcode 9 The use of Swift 3 @objc inference in Swift 4 mode is deprecated?

Examples related to swift3

Xcode 9 Swift Language Version (SWIFT_VERSION) Convert NSDate to String in iOS Swift Waiting until the task finishes Type of expression is ambiguous without more context Swift Removing object from array in Swift 3 Generate your own Error code in swift 3 Swift 3: Display Image from URL add Shadow on UIView using swift 3 how to open an URL in Swift3 Correctly Parsing JSON in Swift 3