NSPredicate Out of Order / Дополнительная информация - PullRequest
0 голосов
/ 13 января 2019

Допустим, у меня есть два объекта:

  • Большой велосипед (размер = большой, тип = велосипед)
  • Маленький велосипед (размер = маленький, тип = велосипед)

Если я сделаю следующий запрос: «Большой синий велосипед», я должен получить обратно объект Большой велосипед.

Я пытаюсь выяснить, как реализовать это с помощью функции NSPredicate.

В настоящее время я использую что-то вроде следующего:

let typePredicate = NSPredicate(format: "type CONTAINS[c] %@", text);

Однако, поскольку «Blue» отсутствует в объекте, предикат удалит все объекты из отфильтрованного массива.

Существует ли формат NSPredicate, который позволит мне принять во внимание эти посторонние утверждения и все же вернуть Big Bike из "Big Blue Bike"?

1 Ответ

0 голосов
/ 13 января 2019

Я просто приведу один простой пример, как вы можете достичь этого, это просто пример, чтобы дать некоторую идею, чтобы вы могли продолжить, скажем, мы создадим класс с именем Vehicle, позже мы создадим 2 других класса. как вы только что упомянули, BigBike и SmallBike и после этого увидите, как проанализировать это, используя строку запроса

давайте создадим класс с именем Vehicle этот класс содержит всю информацию, это будет полезно, если у вас есть объекты одного типа в массиве.

 import Foundation

 enum Size {
   case big
   case small
 }

 enum Type {
   case Bike
   case Car
 }

 class Vehicle:NSObject {
    let size:Size
    let type:Type

    init(with vehicleType:Type, andSize vehicleSize:Size) {
      self.size = vehicleSize
      self.type = vehicleType
    }

    override func value(forKey key: String) -> Any? {
      if key == "size" {
           if self.size == .big {
               return "big"
           } else if self.size == .small {
               return "small"
           }
     } else if key == "type" {
           if self.type == .Bike {
              return "bike"
           } else if self.type == .Car {
              return "car"
          }
     }
     return nil
  }

  func vehicleDescription() {
      let aType = (type == .Bike) ? "Bike" : "Car"
      let aSize = (size == .big) ? "Big" : "Small"
      print("this vehicle is \(aType) of size \(aSize)")
  }
}

Теперь мы создадим два объекта, которые вы упомянули в вопросе BigBike и SmallBike, как показано ниже, просто подкласс Vehicle class

import Foundation
class BigBike:Vehicle {

}

и еще один SmallBike

import Foundation
class SmallBike:Vehicle {

}

Теперь у вас есть 2 класса BigBike, и SmallBike теперь позволяет фильтровать эти объекты, созданные из этих 2 классов, у вас есть массив, содержащий объект этих 2 классов, например, давайте возьмем массив и добавим объект BigBike и SmallBike, как показано ниже,

var vehicles:NSMutableArray =  NSMutableArray()
//add some objects for above array like below for testing:
func setupVehicleArray() {
    for i in 0..<15 {
        if i < 5 {
            let vehicle = BigBike(with: .Bike, andSize: .big)
            vehicles.add(vehicle)//append(vehicle)
        }
        if i > 5 && i < 10 {
            let vehicle = BigBike(with: .Bike, andSize: .small)
            vehicles.add(vehicle)
        }
        if i > 11 && i < 15 {
            let vehicle = BigBike(with: .Bike, andSize: .big)
            vehicles.add(vehicle)
        }
    }
}

теперь vehicles содержит объекты BigBike и SmallBike, теперь давайте сделаем запрос и отфильтруем эти объекты, используя предикат

 func makeQuery() {
    let query = "big blue bike"
    let aPredicate = NSPredicate { (obj:Any?, test:[String : Any]?) -> Bool in
        var checkFurther = false
        if let aObj = obj as? Vehicle {
            if let size = aObj.value(forKey: "size") as? String {
                if query.contains(size) {
                    checkFurther = true
                }
            }
            if let type = aObj.value(forKey: "type") as? String {
                if query.contains(type) {
                    if checkFurther {
                        return true
                    }
                }
            }
        }
        return false
        }

    let filteredArray = vehicles.filtered(using: aPredicate)
    for aVehicle:Vehicle in filteredArray as! [Vehicle] {
        aVehicle.vehicleDescription()
    }
}

Это просто пример, который вы можете попробовать, он также дает значения для других запросов, и вы можете изменять предикат в соответствии с вашими требованиями.

выше дает результат как ниже:

this vehicle is Bike of size Big this vehicle is Bike of size Big this vehicle is Bike of size Big this vehicle is Bike of size Big this vehicle is Bike of size Big this vehicle is Bike of size Big this vehicle is Bike of size Big this vehicle is Bike of size Big

если вы измените строку запроса на small green bike, вы получите результат как this vehicle is Bike of size Small this vehicle is Bike of size Small this vehicle is Bike of size Small this vehicle is Bike of size Small

Надеюсь, это поможет ..:)

...