Использование Predicate в Swift

Я работаю над учебником здесь (изучая Swift) для своего первого приложения: http://www.appcoda.com/search-bar-tutorial-ios7/

Я застрял в этой части (Objective-C code):

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope
{
    NSPredicate *resultPredicate = [NSPredicate predicateWithFormat:@"name contains[c]         %@", searchText];
    searchResults = [recipes filteredArrayUsingPredicate:resultPredicate];
}

Может ли кто-нибудь посоветовать, как создать эквивалент для NSPredicate в Swift?

Ответ 1

Это действительно просто синтаксический переключатель. Итак, у нас есть этот метод:

[NSPredicate predicateWithFormat:@"name contains[c] %@", searchText];

В Swift конструкторы пропускают часть "blahWith..." и просто используют имя класса как функцию, а затем идут прямо к аргументам, поэтому [NSPredicate predicateWithFormat: …] станет NSPredicate(format: …). (Для другого примера [NSArray arrayWithObject: …] станет NSArray(object: …). Это обычный шаблон в Swift.)

Итак, теперь нам просто нужно передать аргументы конструктору. В Objective-C литералы NSString выглядят как @"", но в Swift мы просто используем кавычки для строк. Это дает нам:

let resultPredicate = NSPredicate(format: "name contains[c] %@", searchText)

И на самом деле это именно то, что нам нужно здесь.

(Кстати, вы заметите, что некоторые другие ответы вместо этого используют строку формата, например "name contains[c] \(searchText)". Это неверно. Это использует интерполяцию строк, которая отличается от форматирования предикатов и обычно не работает для этого.)

Ответ 2

Работа с предикатом довольно долгое время. Вот мой вывод (SWIFT)

//Customizable! (for me was just important if at least one)
request.fetchLimit = 1


//IF IS EQUAL

//1 OBJECT
request.predicate = NSPredicate(format: "name = %@", txtFieldName.text)

//ARRAY
request.predicate = NSPredicate(format: "name = %@ AND nickName = %@", argumentArray: [name, nickname])


// IF CONTAINS

//1 OBJECT
request.predicate = NSPredicate(format: "name contains[c] %@", txtFieldName.text)

//ARRAY
request.predicate = NSPredicate(format: "name contains[c] %@ AND nickName contains[c] %@", argumentArray: [name, nickname])

Ответ 3

Пример использования в swift 2.0

let dataSource = [
    "Domain CheckService",
    "IMEI check",
    "Compliant about service provider",
    "Compliant about TRA",
    "Enquires",
    "Suggestion",
    "SMS Spam",
    "Poor Coverage",
    "Help Salim"
]
let searchString = "Enq"
let predicate = NSPredicate(format: "SELF contains %@", searchString)
let searchDataSource = dataSource.filter { predicate.evaluateWithObject($0) }

Вы получите (игровая площадка)

введите описание изображения здесь

Ответ 4

Используйте код ниже:

 func filterContentForSearchText(searchText:NSString, scopes scope:NSString)
{
    //var searchText = ""

    var resultPredicate : NSPredicate = NSPredicate(format: "name contains[c]\(searchText)", nil)

    //var recipes : NSArray = NSArray()

    var searchResults = recipes.filteredArrayUsingPredicate(resultPredicate)
}

Ответ 5

Я думаю, что это был бы лучший способ сделать это в Swift:

func filterContentForSearchText(searchText:NSString, scope:NSString)
{
   searchResults = recipes.filter { name.rangeOfString(searchText) != nil  }
}

Ответ 6

В быстрой 2.2

func filterContentForSearchText(searchText: String, scope: String) {
    var resultPredicate = NSPredicate(format: "name contains[c]         %@", searchText)
    searchResults = (recipes as NSArray).filteredArrayUsingPredicate(resultPredicate)
}

В быстрой версии 3.0

func filterContent(forSearchText searchText: String, scope: String) {
        var resultPredicate = NSPredicate(format: "name contains[c]         %@", searchText)
        searchResults = recipes.filtered(using: resultPredicate)
    }