简体   繁体   中英

swift remove item from array after `filter` or by finding `firstIndex that `contains`

I have two arrays of Book s

var tempArray = [Book]()
var filteredArray = [Book]()

where

struct Book: Codable, Equatable {
    let category: String
    let title: String
    let author: String
}

I want to remove a book from tempArray if a title matches. I can filter tempArray searching for "Some title" like this

filteredArray = tempArray.filter( { $0.title.range(of: "Some Title", options: .caseInsensitive) != nil } )

I'm trying this to remove

if let i = tempArray.firstIndex(of: { $0.title.contains("Some Title") }) {
        tempArray.remove(at: i)
    }

but get this Cannot invoke 'contains' with an argument list of type '(String)' . Advice to fix this error? Or alternatively, can the element be removed while filtering?

You are using the wrong method. It should be func firstIndex(where predicate: (Self.Element) throws -> Bool) rethrows -> Self.Index? instead of func firstIndex(of element: Book) -> Int?

if let i = tempArray.firstIndex(where: { $0.title.contains("Some Title") }) {
    tempArray.remove(at: i)
}

Another option is to use RangeReplaceableCollection 's method mutating func removeAll(where shouldBeRemoved: (Book) throws -> Bool) rethrows :

tempArray.removeAll { $0.title.contains("Some Title") }

Playground testing:

struct Book: Codable, Equatable {
    let category, title, author: String
}

var tempArray: [Book] = [.init(category: "", title: "Some Title", author: "")]
print(tempArray)   // "[__lldb_expr_12.Book(category: "", title: "Some Title", author: "")]\n"

tempArray.removeAll { $0.title.contains("Some Title") }
print(tempArray)  //  "[]\n"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM