Использование предиката в 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?

795   8  

8 ответов:

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

[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)". Это неверно. Это использует интерполяцию строк, которая отличается от форматирования предикатов и обычно не работает для этого.)

работа с предикатом в течение довольно долгого времени. Вот мой вывод (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])

пример использования в 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() }

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

enter image description here

вы можете использовать фильтры, доступные в swift для фильтрации содержимого из массива вместо использования предиката, как в Objective-C.

пример в Swift 4.0 выглядит следующим образом:

var stringArray = ["foundation","coredata","coregraphics"]
stringArray = stringArray.filter { .contains("core") }

В приведенном выше примере, так как каждый элемент массива является строкой, вы можете использовать contains метод фильтрации массива.

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

используйте следующий код:

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

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

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

в swift 2.2

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

в swift 3.0

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

/ / изменить "имя" и "значение" в соответствии с данными массива.

/ / измените имя "yourDataArrayName" в соответствии с вашим массивом(NSArray).

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

    if let sortedDta = yourDataArrayName.filtered(using: resultPredicate) as? NSArray {

 //enter code here.

        print(sortedDta)
    }

Comments

    Ничего не найдено.