ios - logo - swift language



Trova un oggetto nella matrice? (11)

È possibile filtrare l'array e quindi selezionare il primo elemento, come mostrato in Trova oggetto con proprietà nell'array.

Oppure si definisce un'estensione personalizzata

struct T {
    var name : String
}

let array = [T(name: "bar"), T(name: "baz"), T(name: "foo")]

if let item = array.findFirstMatching( { $0.name == "foo" } ) {
    // item is the first matching array element
} else {
    // not found
}

Esempio di utilizzo:

if let item = array.first(where: { $0.name == "foo" }) {
    // item is the first matching array element
} else {
    // not found
}

In Swift 3 puoi usare first(where:) metodo esistente first(where:) (come menzionato in un commento ):

func index(where predicate: @noescape Element throws -> Bool) rethrows -> Int?

Swift ha qualcosa come _.findWhere in Underscore.js?

Ho una serie di strutture di tipo T e vorrei verificare se la matrice contiene un oggetto struct il cui name è uguale a Foo .

Ho provato a usare find() e filter() ma funzionano solo con tipi primitivi, ad esempio String o Int . Genera un errore in caso di non conformità al protocollo Equitable o qualcosa del genere.


Answer #1

È possibile utilizzare il metodo index disponibile su Array con un predicato ( consultare la documentazione di Apple qui ).

func index(where predicate: (Element) throws -> Bool) rethrows -> Int?

Per il tuo esempio specifico questo sarebbe:

Swift 5.0

if let i = array.index(where: { $0.name == Foo }) {
    return array[i]
}

Swift 3.0

if let i = array.indexOf({ $0.name == Foo }) {
    return array[i]
}

Swift 2.0

array.first{$0.name == "Foo"}

Answer #2

FWIW, se non si desidera utilizzare la funzione o l'estensione personalizzata, è possibile:

let array = [ .... ]
if let found = find(array.map({ $0.name }), "Foo") {
    let obj = array[found]
}

Questo genera prima l'array di name , quindi find da esso.

Se hai un array enorme, potresti voler fare:

if let found = find(lazy(array).map({ $0.name }), "Foo") {
    let obj = array[found]
}

o forse:

if let found = find(lazy(array).map({ $0.name == "Foo" }), true) {
    let obj = array[found]
}

Answer #3

L'uso contains :

import Foundation
class Model: NSObject {  }

Oppure potresti provare ciò che Martin ti ha indicato nei commenti e dare filter altro tentativo al filter : Trova oggetto con proprietà in array .


Answer #4

Un altro modo per ottenere l'accesso a array.index (di: Any) è dichiarare l'oggetto

import Dollar

let found = $.find(array) { $0.name == "Foo" }

Answer #5

Usa Dollar che è Lo-Dash o Underscore.js per Swift:

class Person : Equatable { //<--- Add Equatable protocol
    let name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    //Add Equatable functionality:
    static func == (lhs: Person, rhs: Person) -> Bool {
        return (lhs.name == rhs.name)
    }
}

Answer #6

Swift 2 o successivo

È possibile combinare indexOf e map per scrivere una funzione "trova elemento" in una sola riga.

var yourItem:YourType!
if contains(yourArray, item){
    yourItem = item
}

L'uso di filter + per first sembra più pulito, ma filter valuta tutti gli elementi dell'array. indexOf + map sembra complicato, ma la valutazione si interrompe quando viene trovata la prima corrispondenza nell'array. Entrambi gli approcci hanno pro e contro.


Answer #7

Swift 3

Se hai bisogno dell'oggetto usa:

if let index = array.index(where: { $0.name == "Foo" }) {
    return array[index]
}

(Se hai più di un oggetto chiamato "Foo", il first restituirà il primo oggetto da un ordine non specificato)


Answer #8

Swift 3

let array = [T(name: "foo"), T(name: "Foo"), T(name: "FOO")]
let foundValue = array.indexOf { $0.name == "Foo" }.map { array[$0] }
print(foundValue) // Prints "T(name: "Foo")"

Answer #9

Swift 3.0

for myObj in myObjList where myObj.name == "foo" {
 //object with name is foo
}

Swift 2.1

Il filtro nelle proprietà degli oggetti è ora supportato in swift 2.1. È possibile filtrare l'array in base a qualsiasi valore della struttura o della classe, qui è un esempio

for myObj in myObjList where myObj.Id > 10 {
 //objects with Id is greater than 10
}

O

extension Array {

    // Returns the first element satisfying the predicate, or `nil`
    // if there is no matching element.
    func findFirstMatching<L : BooleanType>(predicate: T -> L) -> T? {
        for item in self {
            if predicate(item) {
                return item // found
            }
        }
        return nil // not found
    }
}

Answer #10

Swift 4 ,

Un altro modo per raggiungere questo obiettivo utilizzando la funzione filtro,

if yourArray.contains(item) {
   //item found, do what you want
}
else{
   //item not found 
   yourArray.append(item)
}




swift