RK.
RK.

Reputation: 887

Remove the last occurrence of an element in a Swift array

I need to remove the last occurrence of a specific element in a [Bool] Array. For example in JavaScript this would be:

var k = [true, true, false];
k.splice(k.lastIndexOf(true), 1);
==> [true, false]

How would I achieve the same behavior in Swift?

Upvotes: 2

Views: 4788

Answers (3)

Leo Dabus
Leo Dabus

Reputation: 236370

Xcode 8.2 • Swift 3.0.2

var k = [true, true, true, false, true, false]

if let index = k.reversed().index(of: true) {
    k.remove(at: index.base - 1)
}

print(k)   // "[true, true, true, false, false]"

If you would like to create an extension to add this functionality to Array you need to constrain it to equatable elements:

extension Array where Element: Equatable {
    ///  Returns the last index where the specified value appears in the collection.
    ///  After using lastIndex(of:) to find the last position of a particular element in a collection, you can use it to access the element by subscripting.
    /// - Parameter element: The element to find the last Index
    func lastIndex(of element: Element) -> Index? {
        if let index = reversed().index(of: element) {
            return  index.base - 1
        }
        return nil
    }
    /// Removes the last occurrence where the specified value appears in the collection.
    /// - Returns: True if the last occurrence element was found and removed or false if not.
    /// - Parameter element: The element to remove the last occurrence.
    @discardableResult
    mutating func removeLastOccurrence(of element: Element) -> Bool {
        if let index = lastIndex(of: element) {
            remove(at: index)
            return true
        }
        return false
    }
}

Playground testing

var k = [true, true, true, false, true, false]

k.removeLastOccurrence(of: true)
print(k)                        // "[true, true, true, false, false]"

Upvotes: 6

Stuart
Stuart

Reputation: 37053

You can easily find the last occurrence of a value by enumerating in reverse. When you find the value you're looking for, just remove it and break from the loop. Use reverse() enumerate the range of indexes in reverse order:

for i in array.indices.reversed() where array[i] == searchValue {
    array.remove(at: i)
    break
}

Upvotes: 7

ezig
ezig

Reputation: 1229

I don't think there's a builtin function like lastIndexOf, so it's a bit more work.

var removeIndex: Int?

for (index, item) in enumerate(arr) {
    if item == search {
        removeIndex = index 
    }
}

if let removeIndex = removeIndex {
    arr.removeAtIndex(removeIndex)
}

Where arr is the array you're searching (k in your example) and search is what you're searching for (true in your example).

Upvotes: 2

Related Questions