web-dev-qa-db-ja.com

Swiftの[AnyObject]のフィルター配列

SwiftにはAnyObjectオブジェクトの配列があります。各オブジェクトには、名前、タイプ、場所などのレストランの属性があります。タイプ「寿司」を含む配列内のすべてのオブジェクトを保持する場合、配列をフィルター処理するにはどうすればよいですか。

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!)
26
Onichan

配列objectsは、PFObjectオブジェクトの配列です。したがって、配列を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の宣言に応じて少し異なりますが、これは私たちとは共有していませんが、うまくいけばこの考えを示しています。

54
Rob

配列objectsRestaurant(s)次のコードは機能します。

Restaurantは次のようなものだとしましょう。

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)
}

更新:今私はobjectsPFObject(s)の配列であると仮定しています。以前のコードを無視してこれを試してください:

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

おそらく再びクラッシュするかもしれませんが、問題はRestaurant.Typeのタイプがわからないことです。私はしようとしています。次のエラーメッセージでもっと役立つ情報が得られるかもしれません。

8
Luca Angeletti

Swift 3ソリューション

配列で filter method を使用します。

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

またはreturn Bool(restaurant.type.contains("sushi")) typeが配列の場合。

8
Derek Soike

Swift 2.0、In Swift 2.0としてRobのコードを使用すると、次のようなエラーが発生します-

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

enter image description here

ただし、以下のようにif-letの代わりにguardステートメントを使用することで解決できます-

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

以下に示すような解決策があります。

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