webentwicklung-frage-antwort-db.com.de

Filter Array von [AnyObject] in Swift

Ich habe ein Array von AnyObject Objekten in Swift. Jedes Objekt hat Attribute eines Restaurants, wie Name, Typ, Ort usw. Wie kann ich das Array filtern, wenn ich alle Objekte im Array behalten möchte, die den Typ "Sushi" enthalten.

Beispielarray von [AnyObject] Mit 2 Objekten. Der Filter sollte das erste Objekt behalten (Typ: Sushi):

[<Restaurant: 0x7ff302c8a4e0, objectId: LA74J92QDA, localId: (null)> {
    City = "New York";
    Country = "United States";
    Name = Sumo Japan;
    Type = Sushi, Japanese, Asian;
}, <Restaurant: 0x7ff302daa790, objectId: 0aKFrpKN46, localId: (null)> {
    City = "New York";
    Country = "United States";
    Name = Little Italy;
    Type = Italian, Pizza;
}]

Aktueller Code (aber ich bin nicht sicher, ob der Filter ein Array von [AnyObject] Durchsuchen kann):

var query = PFQuery(className:"Restaurant")
query.whereKey("RestaurantLoc", nearGeoPoint:userGeoPoint, withinMiles:50)
query.limit = 2
query.findObjectsInBackgroundWithBlock {
    (objects: [AnyObject]!, error: NSError!) -> Void in
    if objects != nil {
        println("list of objects of nearby")
        println(objects)
        let searchString = "Sushi"
        let predicate = NSPredicate(format: "Type CONTAINS[cd] %@", searchString);

        //Line below gives error: '[AnyObject]' does not have a member named 'filteredArrayUsingPredicate'
        //let filteredArray = objects.filteredArrayUsingPredicate(predicate!)
26
Onichan

Ihr Array objects ist ein Array von PFObject Objekten. Um also das Array zu filter, könnten Sie etwas tun wie:

let filteredArray = objects.filter() {
    if let type = ($0 as PFObject)["Type"] as String {
        return type.rangeOfString("Sushi") != nil
    } else {
        return false
    }
}

Meine ursprüngliche Antwort, basierend auf der Annahme, dass es sich um benutzerdefinierte Restaurant -Objekte handelt, lautet wie folgt:


Sie können die Methode filter verwenden.

Nehmen wir an, Restaurant wurde wie folgt definiert:

class Restaurant {
    var city: String
    var name: String
    var country: String
    var type: [String]!

    init (city: String, name: String, country: String, type: [String]!) {
        ...
    }
}

Unter der Annahme, dass type ein Array von Zeichenfolgen ist, würden Sie folgendermaßen vorgehen:

let filteredArray = objects.filter() {contains(($0 as Restaurant).type, "Sushi")}

Wenn Ihr Array von Typen nil sein könnte, würden Sie eine bedingte Entpackung durchführen:

let filteredArray = objects.filter() {
    if let type = ($0 as Restaurant).type as [String]! {
        return contains(type, "Sushi")
    } else {
        return false
    }
}

Die Einzelheiten variieren ein wenig in Abhängigkeit von Ihrer Erklärung von Restaurant, die Sie uns nicht mitgeteilt haben, aber dies veranschaulicht hoffentlich die Idee.

54
Rob

Ok, wenn das Array Objekte enthält nur Restaurant (s) der folgende Code funktioniert.

Nehmen wir an, das Restaurant ist ungefähr so:

enum RestaurantType {
    case Sushi, Japanese, Asian
}

class Restaurant {
    var type = [RestaurantType]()
    // more properties here...
}

Zunächst definieren wir eine Reihe von Restaurants.

var restaurants = objects as [Restaurant]

Dann können wir es filtern:

var sushiRestaurants = restaurants.filter { (restaurant : Restaurant) -> Bool in
    return contains(restaurant.type, .Sushi)
}

pdate: Nun gehe ich davon aus, dass objects ein Array von PFObject (s) ist. Ignoriere einfach meinen vorherigen Code und versuche dies:

var restaurants = objects as [PFObject]
var sushiRestaurants = restaurants.filter { (restaurant : PFObject) -> Bool in
    return contains(restaurant["Type"], "Sushi")
}

Vielleicht stürzt es wieder ab, das Problem ist, dass ich die Art des Restaurants nicht kenne. Ich versuche es. Möglicherweise liefert die nächste Fehlermeldung weitere nützliche Informationen.

8
Luca Angeletti

Swift 3-Lösung

Verwenden Sie die Filtermethode für ein Array.

let restaurants: [Restaurants] = [...]
restaurants.filter({(restaurant) in
    return Bool(restaurant.type == "sushi")
})

oder return Bool(restaurant.type.contains("sushi")), wenn type ein Array ist.

8
Derek Soike

Die Änderung von Robs Antwort als Swift 2.0, In Swift 2.0 unter Verwendung von Robs Code führt zu folgendem Fehler:

initializer for conditional binding must have optional type, not 'string'

enter image description here

Es kann jedoch gelöst werden, indem eine guard-Anweisung anstelle der folgenden if-let-Anweisung verwendet wird.

let filteredArray = objects.filter() {
            guard let type = ($0 as PFObject)["Type"] as String else {
                return false
            } 
            return type.rangeOfString("Sushi") != nil
        }
5
AppsWise

Ich habe eine Lösung wie unten angegeben.

func filterByCuisineType(list: [Restaurant]) -> [Restaurant]{

    if self.cuisineTypes.count == 0 {
        return list
    }

    let array: [Restaurant] =  list.filter { (restaurant) -> Bool in

        for cuisineName in self.cuisineTypes{

            let isContained: Bool = restaurant.cuisineType.contains(cuisineName)

            if isContained {
                return true
            }
        }

        return false
    }

    return array
}
3
Coder_A_D