J'ai un tableau d'objets AnyObject
dans Swift. Chaque objet a des attributs d'un restaurant, tels que le nom, le type, le lieu, etc. Comment puis-je filtrer le tableau si je veux conserver tous les objets du tableau qui contiennent le type: "Sushi".
Exemple de tableau de [AnyObject]
avec 2 objets. Le filtre doit conserver le premier objet (type: 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;
}]
Code actuel (mais je ne sais pas si le filtre peut rechercher dans un tableau de [AnyObject]
):
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!)
Votre tableau, objects
, est un tableau d'objets PFObject
. Ainsi, pour filter
le tableau, vous pourriez faire quelque chose comme:
let filteredArray = objects.filter() {
if let type = ($0 as PFObject)["Type"] as String {
return type.rangeOfString("Sushi") != nil
} else {
return false
}
}
Ma réponse originale, basée sur l'hypothèse que nous avions affaire à des objets Restaurant
personnalisés, est ci-dessous:
Vous pouvez utiliser la méthode filter
.
Supposons que Restaurant
soit défini comme suit:
class Restaurant {
var city: String
var name: String
var country: String
var type: [String]!
init (city: String, name: String, country: String, type: [String]!) {
...
}
}
Donc, en supposant que type
est un tableau de chaînes, vous feriez quelque chose comme:
let filteredArray = objects.filter() {contains(($0 as Restaurant).type, "Sushi")}
Si votre tableau de types pouvait être nil
, vous en feriez un déballage conditionnel:
let filteredArray = objects.filter() {
if let type = ($0 as Restaurant).type as [String]! {
return contains(type, "Sushi")
} else {
return false
}
}
Les détails varieront un peu selon votre déclaration de Restaurant
, que vous n'avez pas partagée avec nous, mais j'espère que cela illustre l'idée.
Ok, si le tableau objets ne contient que Restaurant (s) le code suivant fonctionne.
Disons que le restaurant est quelque chose comme ça:
enum RestaurantType {
case Sushi, Japanese, Asian
}
class Restaurant {
var type = [RestaurantType]()
// more properties here...
}
Tout d'abord, définissons un tableau de restaurant (s).
var restaurants = objects as [Restaurant]
Ensuite, nous pouvons le filtrer:
var sushiRestaurants = restaurants.filter { (restaurant : Restaurant) -> Bool in
return contains(restaurant.type, .Sushi)
}
Mise à jour: Maintenant, je suppose que objets est un tableau de PFObject (s) Ignorez simplement mon code précédent et essayez ceci:
var restaurants = objects as [PFObject]
var sushiRestaurants = restaurants.filter { (restaurant : PFObject) -> Bool in
return contains(restaurant["Type"], "Sushi")
}
Peut-être que ça va planter à nouveau, le problème est que je ne connais pas le type de Restaurant.Type. J'essaie. Peut-être que le prochain message d'erreur fournira des informations plus utiles.
Solution Swift 3
Utilisez la méthode de filtrage sur un tableau.
let restaurants: [Restaurants] = [...]
restaurants.filter({(restaurant) in
return Bool(restaurant.type == "sushi")
})
ou return Bool(restaurant.type.contains("sushi"))
si type est un tableau.
La modification de la réponse de Rob comme Swift 2.0, In Swift 2.0 utilisant le code de Rob donne l'erreur comme suit -
initializer for conditional binding must have optional type, not 'string'
Cependant, il peut être résolu en utilisant la déclaration de garde au lieu de if-let comme ci-dessous -
let filteredArray = objects.filter() {
guard let type = ($0 as PFObject)["Type"] as String else {
return false
}
return type.rangeOfString("Sushi") != nil
}
J'ai une solution comme indiqué ci-dessous.
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
}