Sử dụng vị ngữ trong Swift


93

Tôi đang làm việc thông qua hướng dẫn ở đây (học Swift) cho ứng dụng đầu tiên của tôi: http://www.appcoda.com/search-bar-tutorial-ios7/

Tôi bị mắc kẹt ở phần này (mã Objective-C):

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

Bất cứ ai có thể tư vấn làm thế nào để tạo một tương đương cho NSPredicate trong Swift?

Câu trả lời:


157

Đây thực sự chỉ là một cú pháp chuyển đổi. OK, vì vậy chúng tôi có cuộc gọi phương thức này:

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

Trong Swift, các hàm tạo bỏ qua phần "blahWith…" và chỉ sử dụng tên lớp như một hàm và sau đó đi thẳng đến các đối số, như vậy [NSPredicate predicateWithFormat: …]sẽ trở thành NSPredicate(format: …). (Đối với một ví dụ khác, [NSArray arrayWithObject: …]sẽ trở thành NSArray(object: …). Đây là một mẫu thông thường trong Swift.)

Vì vậy, bây giờ chúng ta chỉ cần truyền các đối số cho hàm tạo. Trong Objective-C, các ký tự NSString trông giống như vậy @"", nhưng trong Swift, chúng tôi chỉ sử dụng dấu ngoặc kép cho các chuỗi. Vì vậy, điều đó cho chúng ta:

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

Và trên thực tế, đó chính xác là những gì chúng ta cần ở đây.

(Tình cờ, bạn sẽ nhận thấy một số câu trả lời khác thay vào đó sử dụng chuỗi định dạng như "name contains[c] \(searchText)". Điều đó không chính xác. Điều đó sử dụng phép nội suy chuỗi, khác với định dạng vị từ và thường sẽ không hoạt động cho điều này.)


Cảm ơn. Bạn cứu tôi một ngày!
Hugo

2
Để giải quyết dòng thứ hai trong phương pháp của bạn, bạn có thể sử dụng vị từ là:searchResults = recipes.filter { resultPredicate.evaluateWithObject($0) }
Ben Packard

43

Làm việc với vị ngữ trong một thời gian khá dài. Đây là kết luận của tôi (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])

1
Bằng gì với LIKE 'a%z'?
TomSawyer

@ Jiří Zahálka Yêu cầu nghe nghĩa là gì?
Muju

28

Ví dụ về cách sử dụng trong 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) }

Bạn sẽ nhận được (sân chơi)

nhập mô tả hình ảnh ở đây


Điều gì xảy ra nếu ... Nếu tôi có một loạt các từ điển? Làm cách nào để phân tích cú pháp để lấy dữ liệu?
Revathy Durairajan,

1
@RevathyDurairajan bạn cần SELF.yourkeyname để lọc mảng từ điển.
Pawan Rai

11

Bạn có thể sử dụng các bộ lọc có sẵn nhanh chóng để lọc nội dung từ một mảng thay vì sử dụng một vị từ như trong Objective-C.

Một ví dụ trong Swift 4.0 như sau:

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

Trong ví dụ trên, vì mỗi phần tử trong mảng là một chuỗi nên bạn có thể sử dụng containsphương thức để lọc mảng.

Nếu mảng chứa các đối tượng tùy chỉnh, thì các thuộc tính của đối tượng đó có thể được sử dụng để lọc các phần tử tương tự.


6

Sử dụng mã Dưới đây:

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

1
Đối với một số lý do bằng văn bản nó như thế không làm việc cho tôi tuy nhiên làm let myPredicateString = "tên chứa [c] (searchText)" và sau đó làm var resultPredicate: NSPredicate = NSPredicate (định dạng: myPredicateString) đã
AppHandwerker

5

Tôi nghĩ rằng đây sẽ là một cách tốt hơn để làm điều đó trong Swift:

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

1
Điều này khó hiểu hơn nếu bạn đang lọc a Sequence, nhưng có những trường hợp bạn sẽ cần một NSPredicate, như khi xử lý NSFetchedResultsController.
Jarsen

1

Trong 2.2 nhanh chóng

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

Trong 3.0 nhanh chóng

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

1

// thay đổi "tên" và "giá trị" theo dữ liệu mảng của bạn.

// Thay đổi tên "yourDataArrayName" thành mảng của bạn (NSArray).

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

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

 //enter code here.

        print(sortedDta)
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.