在Swift中过滤[AnyObject]的数组

时间:2014-12-30 17:20:36

标签: swift filter parse-platform

我在Swift中有一组AnyObject个对象。每个对象都有一个餐馆的属性,例如名称,类型,位置等。如果我想保留数组中包含类型的所有对象:“Sushi”,我该如何过滤数组。

包含2个对象的[AnyObject]示例数组。过滤器应该保留第一个对象(类型:寿司):

[<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;
}]

当前代码(但我不确定过滤器是否可以搜索[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!)

5 个答案:

答案 0 :(得分:54)

您的数组objectsPFObject个对象的数组。因此,对于filter数组,您可以执行以下操作:

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

基于我们处理自定义Restaurant对象的假设,我的原始答案如下:


您可以使用filter方法。

我们假设Restaurant的定义如下:

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

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

因此,假设type是一个字符串数组,您可以执行以下操作:

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

如果您的类型数组可能是nil,那么您需要对其进行条件展开:

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

根据您未与我们分享的Restaurant声明,细节会有所不同,但希望这说明了这个想法。

答案 1 :(得分:8)

好的,如果数组 对象 仅包含 餐厅 ,则以下代码可以正常运行。< / p>

让我们说餐馆是这样的:

enum RestaurantType {
    case Sushi, Japanese, Asian
}

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

首先让我们定义一个餐厅阵列。

var restaurants = objects as [Restaurant]

然后我们可以过滤它:

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

<强>更新 现在我假设对象 PFObject (s)的数组 只需忽略我之前的代码并试试这个:

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

也许它会再次崩溃,问题是我不知道Restaurant.Type的类型。我正在努力。也许下一条错误消息将提供更多有用的信息。

答案 2 :(得分:8)

Swift 3解决方案

在阵列上使用filter method

let restaurants: [Restaurants] = [...]
restaurants.filter({(restaurant) in
    return Bool(restaurant.type == "sushi")
})
如果type是数组,则

return Bool(restaurant.type.contains("sushi"))

答案 3 :(得分:5)

将Rob的答案修改为Swift 2.0,在swift 2.0中使用Rob的代码会产生如下错误 -

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

enter image description here

然而,可以通过使用guard语句而不是if-let来解决它 -

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

答案 4 :(得分:3)

我有一个解决方案,如下所示。

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
}