Menggunakan Predikat di Swift

93

Saya mengerjakan tutorial di sini (mempelajari Swift) untuk aplikasi pertama saya: http://www.appcoda.com/search-bar-tutorial-ios7/

Saya terjebak di bagian ini (kode Objective-C):

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

Adakah yang bisa menyarankan cara membuat yang setara untuk NSPredicate di Swift?

levitatejay.dll
sumber

Jawaban:

158

Ini benar-benar hanya sakelar sintaks. Oke, jadi kami memiliki panggilan metode ini:

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

Di Swift, konstruktor melewati bagian "blahWith…" dan cukup gunakan nama kelas sebagai fungsi lalu langsung ke argumen, jadi [NSPredicate predicateWithFormat: …]akan menjadi NSPredicate(format: …). (Untuk contoh lain, [NSArray arrayWithObject: …]akan menjadi NSArray(object: …). Ini adalah pola reguler di Swift.)

Jadi sekarang kita hanya perlu meneruskan argumen ke konstruktor. Di Objective-C, literal NSString terlihat seperti itu @"", tetapi di Swift kami hanya menggunakan tanda kutip untuk string. Jadi itu memberi kita:

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

Dan sebenarnya itulah yang kita butuhkan di sini.

(Kebetulan, Anda akan melihat beberapa jawaban lain yang menggunakan format string seperti "name contains[c] \(searchText)". Itu tidak benar. Itu menggunakan interpolasi string, yang berbeda dari pemformatan predikat dan umumnya tidak akan berfungsi untuk ini.)

Membuang
sumber
Terima kasih. Anda menyelamatkan saya suatu hari nanti!
Hugo
2
Untuk mengatasi baris kedua metode Anda, Anda dapat menggunakan predikat sebagai:searchResults = recipes.filter { resultPredicate.evaluateWithObject($0) }
Ben Packard
43

Bekerja dengan predikat cukup lama. Ini kesimpulan saya (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])
Jiří Zahálka
sumber
1
Apa yang sama dengan LIKE 'a%z'?
TomSawyer
@ Jiří Zahálka Apa artinya permintaan dengar?
Muju
28

Contoh cara menggunakan di 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) }

Anda akan mendapatkan (taman bermain)

masukkan deskripsi gambar di sini

gbk
sumber
Bagaimana jika ... Jika saya memiliki berbagai kamus? Bagaimana cara saya mengurai untuk mendapatkan data?
Revathy Durairajan
1
@RevathyDurairajan Anda membutuhkan SELF.yourkeyname untuk memfilter array kamus.
Pawan Rai
11

Anda dapat menggunakan filter yang tersedia dengan cepat untuk memfilter konten dari larik alih-alih menggunakan predikat seperti di Objective-C.

Contoh di Swift 4.0 adalah sebagai berikut:

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

Dalam contoh di atas, karena setiap elemen dalam array adalah string, Anda dapat menggunakan containsmetode untuk memfilter array.

Jika array berisi objek kustom, properti objek tersebut dapat digunakan untuk memfilter elemen dengan cara yang sama.

Gurunath Sripad
sumber
6

Gunakan kode Di Bawah Ini:

 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)
}
PREMKUMAR
sumber
1
Untuk beberapa alasan menulis seperti itu tidak berhasil untuk saya namun melakukan biarkan myPredicateString = "name contains [c] (searchText)" dan kemudian melakukan var resultPredicate: NSPredicate = NSPredicate (format: myPredicateString) lakukan
AppHandwerker
5

Saya pikir ini akan menjadi cara yang lebih baik untuk melakukannya di Swift:

func filterContentForSearchText(searchText:NSString, scope:NSString)
{
   searchResults = recipes.filter { name.rangeOfString(searchText) != nil  }
}
Harris
sumber
1
Ini lebih idiomatis jika Anda memfilter a Sequence, tetapi ada kasus di mana Anda memerlukan NSPredicate, seperti saat menangani NSFetchedResultsController.
Jarsen
1

Dengan cepat 2.2

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

Dalam 3.0 cepat

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

// ubah "nama" dan "nilai" sesuai dengan data array Anda.

// Ubah nama "yourDataArrayName" sesuai dengan array Anda (NSArray).

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

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

 //enter code here.

        print(sortedDta)
    }
Hitesh Chauhan
sumber