Bandingkan integer dengan string di NSPredicate
Saya memiliki rangkaian proyek program latihan (kode untuk mereka ada di Objective-C) dan di setiap program yang saya miliki @property (nullable, nonatomic, copy) NSString *scheduleStr;untuk durasi program. Properti ini menyimpan nilai seperti 1 minggu , 2 minggu , 3 minggu , dll. Saya perlu memfilter semua nilai yang lebih besar dari 6 minggu. Saya mencoba menerapkan NSPredicate:
predicates.append(NSPredicate(format: "scheduleStr.integerValue >= 6"))
dan setelah ini saya hanya menerima program dengan durasi 6-9 minggu, tetapi tidak lebih dari 10 minggu, tetapi yang pasti saya memiliki beberapa program dalam database dengan durasi sama dengan 12 minggu. Jika saya mencoba menerapkan sesuatu seperti ini:
predicates.append(NSPredicate(format: "scheduleStr.integerValue >= 10"))
Saya akan menerima hampir semua program. Bagaimana cara mendapatkan semua program dengan lebih dari nilai yang dipilih?
Jawaban
Masalahnya adalah, meskipun Anda menentukan integerValue, saat menggunakan predikat sebagai bagian dari pengambilan, CoreData memperlakukan string Anda sebagai string. Dalam istilah string, 10 weeksadalah "kurang dari" 6 weeks, jadi dikecualikan dari hasil.
Anda harus menyimpan nomor (sebagai Int) daripada menyimpan string. Menambahkan teks "minggu" adalah sesuatu yang Anda lakukan untuk tujuan tampilan. Jika Anda menyimpan nomornya, bukan stringnya, maka CoreData dapat melakukan perbandingan numerik dan predikat Anda akan berfungsi seperti yang Anda harapkan.
Jika Anda benar-benar tidak ingin melakukan itu, ada satu solusi, dan satu peretasan. Solusinya adalah dengan memfilter objek dalam memori, bukan sebagai bagian dari pengambilan. The integerValuekemudian akan diinterpretasikan dengan benar dan perbandingan akan numerik.
Retasannya adalah memaksa CoreData untuk memperlakukan string Anda seolah-olah itu adalah angka, dengan menggunakan fungsi numerik, seperti abs(dengan asumsi Anda hanya memiliki jumlah minggu yang positif, mengambil nilai absolut meninggalkan nilainya tidak berubah):
predicates.append(NSPredicate(format: "abs:(scheduleStr) >= 6"))
Untuk mendapatkan bagian integer dalam string dalam kasus Anda, Anda dapat melihat sesuatu seperti:
Misalkan elemen adalah string Anda
let component = element.components(separatedBy: .letters) // this will give you the non letter values
let integerValues = component.filter({ $0 != "" })
print(integerValues[0]) // As first value in your input string is an integer
Ini akan memberi Anda bagian integer dari string yang dapat digunakan untuk memfilter array.