2015-04-04 26 views
8

Tôi đã rắc rối lọc mảng các từ khóa (chuỗi) trong nhanh chóng, mã của tôi:mảng Swift lọc các chuỗi

self.filteredKeywords=filter(keywords.allValues, {(keyword:NSString) ->            
    Bool in 
    let words=keyword as? NSString 
    return words?.containsString(searchText) 
    }) 

Như AnyObject không thể subtype của NSString, tôi bị mắc kẹt với điều này!

+0

Lỗi chính xác bạn nhận được là gì? Những gì được in nếu bạn thử 'NSLog (" \ (từ khóa) ")'? – Undo

+0

Chỉ cần thông báo rằng bạn đang trả lại tùy chọn. Hy vọng điều này sẽ giúp –

+0

nó không chạy nó mang lại cho tôi những lỗi được đề cập ở trên: "AnyObject không phải là một loại phụ của NSString" – Meseery

Trả lời

16

[Cập nhật cho Swift 2.0]

Như NSString là điện thoại miễn phí bắc cầu để Swift String, chỉ cần tránh những coercions với:

3> ["abc", "bcd", "xyz"].filter() { nil != $0.rangeOfString("bc") } 
$R1: [String] = 2 values { 
    [0] = "abc" 
    [1] = "bcd" 
} 

Nhưng, nếu bạn nghĩ allValues không dây:

(keywords.allValues as? [String]).filter() { nil != $0.rangeOfString("bc") } 

trả về mảng tùy chọn.

4

filter của bạn là trên [AnyObject], nhưng đóng của bạn mất NSString. Những thứ này cần khớp. Ngoài ra, kết quả của bạn cần phải là Bool, không phải là Bool?. Bạn có thể giải quyết những cách đơn giản như thế này:

self.filteredKeywords = filter(keywords.allValues, { 
    let keyword = $0 as? NSString 
    return keyword?.containsString(searchText) ?? false 
}) 

này chấp nhận AnyObject và sau đó cố gắng để ép buộc nó xuống để NSString. Sau đó nó không phân (??) kết quả để đảm bảo nó luôn là Bool.

Tôi khuyên bạn nên xử lý keywords dưới dạng [String:String] thay vì NSDictionary. Điều đó sẽ loại bỏ tất cả các biến chứng của AnyObject. Sau đó, bạn chỉ có thể làm điều này:

self.filteredKeywords = keywords.values.filter { $0.rangeOfString(searchText) != nil } 

Bất cứ khi nào có thể, chuyển đổi bộ sưu tập Foundation thành bộ sưu tập Swift ngay khi có thể và lưu trữ chúng. Nếu bạn có các đối tượng Foundation đến, bạn thường có thể chuyển đổi chúng một cách dễ dàng với các kỹ thuật như:

let dict = nsdict as? [String:String] ?? [:] 

Hoặc bạn có thể làm như sau để chuyển đổi chúng như vậy mà họ sẽ sụp đổ trong debug (nhưng âm thầm "làm việc" trong phiên bản) :

func failWith<T>(msg: String, value: T) -> T { 
    assertionFailure(msg) 
    return value 
} 

let dict = nsdict as? [String:String] ?? failWith("Couldn't convert \(d)", [:]) 
0

Có cả vấn đề với câu trả lời của GoZon cho một số loại dữ liệu nhất định và cũng là cách tốt hơn để thực hiện việc này. Các ví dụ sau đây có thể hiển thị điều này:

let animalArray: NSMutableArray = ["Dog","Cat","Otter","Deer","Rabbit"] 
let filteredAnimals = animalArray.filter { $0.rangeOfString("er") != nil } 
print("filteredAnimals:", filteredAnimals) 

filteredAnimals: [Dog, Cat, Otter, Deer, Rabbit] 

Có thể không phải là bộ bạn mong đợi!

Tuy nhiên này hoạt động tốt theo cách này nếu chúng ta không gõ animalArray như một NSMutableArray:

let animalArray = ["Dog","Cat","Otter","Deer","Rabbit"] 
let filteredAnimals = animalArray.filter { $0.rangeOfString("er") != nil } 
print("filteredAnimals:", filteredAnimals) 

filteredAnimals: [Otter, Deer] 

Tuy nhiên tôi khuyên bạn nên sử dụng $ 0.contains() thay vì $ 0.rangeOfString()! = nil vì nó hoạt động trong cả hai trường hợp và tăng cường khả năng đọc của mã:

let animalArray: NSMutableArray = ["Dog","Cat","Otter","Deer","Rabbit"] 
let filteredAnimals = animalArray.filter { $0.contains("er") } 
print("filteredAnimals:", filteredAnimals) 

filteredAnimals: [Otter, Deer] 
Các vấn đề liên quan