2015-10-30 17 views
18

Trong Swift 2, tôi nhận được một lỗi:Swift: không thể chuyển đổi giá trị của loại để @noescape khi indexOf cuộc gọi, sau khi lọc sử dụng chức năng lọc

Cannot convert value of type '[String:AnyObject]' to expected argument type '@noescape ([String:AnyObject])' throws -> Bool"

//today = NSDate() 
//array : [[String:AnyObject]] 
// I use if let because of we might now get element in the array matching our condition 

if let elementOfArray = array.filter({$0["id"] as? Int == anotherDictionary["matchID"] as? Int && ($0["nextFireDate"] as? NSDate)?.compare(today) == NSComparisonResult.OrderedAscending}).first { 

    let index = array.indexOf(elementOfArray) // error here 
} 

Những gì tôi đang làm sai? Tôi không thể hiểu được. Mục tiêu của tôi, là tìm chỉ mục của mục đó, tôi nghĩ rằng tôi mở cho các giải pháp thay thế, nhưng tất nhiên điều này được ưa thích hơn, bởi vì tôi nghĩ đây là "cách đúng".

+0

Mã thực tế thay cho '...' trông như thế nào? Tôi không biết nếu nó quan trọng, nhưng nó có thể hữu ích nếu ai đó có thể sao chép và dán chính xác những gì bạn đã có vào một sân chơi để xem lỗi chính xác. – nhgrif

+0

@nhgrif Tôi nghĩ rằng điều này không quan trọng, trong vài từ mã này tìm thấy chính xác một hàng bằng khóa từ điển/giá trị khớp. –

+0

Nó có lẽ không quan trọng, nhưng Swift cho phép chúng tôi nhỏ gọn quá nhiều vào quá ít. Các câu hỏi nên được giải thích rõ ràng về vấn đề chính xác là gì. Tôi đang chơi với điều này trong một sân chơi bản thân mình. Chúng ta có thể loại bỏ toàn bộ 'nếu let' thực sự. Bạn nên thực sự đơn giản hóa câu hỏi này xuống đến nơi chỉ có lệnh 'indexOf' và lỗi thực tế được tạo ra là câu hỏi ở đây. – nhgrif

Trả lời

26

Phương thức indexOf trên các mảng Swift không lấy đối tượng của loại phù hợp với loại của mảng. Thay vào đó, nó phải đóng cửa. Việc đóng này lấy một phần tử của kiểu mảng và trả về một bool.

Vì vậy, trên thực tế, chúng tôi không (và không nên) thậm chí bận tâm với cuộc gọi filter trừ khi chúng tôi thực sự cần kết quả mảng. Nếu chúng tôi chỉ tìm kiếm đối tượng đầu tiên vượt qua bất kỳ bài kiểm tra nào bạn đang lọc ... chúng tôi cũng chỉ vượt qua bài kiểm tra tương tự đó cho indexOf. Vì vậy, để giữ cho mọi thứ đơn giản, nếu chúng ta có một chuỗi các chuỗi (và giả sử chúng là tất cả các chuỗi ký tự đơn với rất nhiều sự lặp lại), và tôi muốn tìm chỉ mục đầu tiên của chuỗi "a", chứ không phải là lọc mảng xuống các chuỗi là "a", sau đó tìm chuỗi đầu tiên đã vượt qua thử nghiệm đó bằng phương pháp first và sau đó tìm chỉ mục của đối tượng chính xác đó, thay vào đó, tôi chỉ cần vượt qua thử nghiệm đó vào phương pháp indexOf:

let letters: [String] = ["x", "y", "z", "a", "b", "c"] 

let index = letters.indexOf { 
    $0 == "a" 
} 

Để rõ ràng, nó sẽ hiển thị rs mà chỉ đơn giản là đi qua một yếu tố cá nhân và tìm kiếm mà không làm việc trong một số trường hợp. Nó có thể dựa trên sự phù hợp với giao thức Equatable của Swift. Tôi có thể ví dụ đã đơn giản được sử dụng letters.indexOf("a") ở đây. Trình biên dịch sẽ rất vui. Nhưng rõ ràng, không phải mọi mảng được cấu tạo cần thiết để giữ những thứ phù hợp với Equatable và mảng không thể đưa ra các giả định về cách so sánh các phần tử của nó sau đó. Trong những trường hợp này, bạn sẽ phải sử dụng ví dụ trên về việc đóng một đóng. Có thể đáng lưu ý rằng việc chuyển phần đóng này sang indexOf thay vì lọc đầu tiên và sau đó gọi indexOf sẽ hiệu quả hơn, ngay cả khi mảng của bạn cho phép cách tiếp cận letters.indexOf("a"). Ví dụ, nếu tôi có nhiều chuỗi phức tạp hơn và tôi chỉ muốn chuỗi đầu tiên bắt đầu bằng chữ cái 'a', điều này sẽ hiệu quả hơn rất nhiều so với việc bắt đầu bằng cách lọc mảng ban đầu thành một chuỗi các chuỗi bắt đầu bằng ' a '.

+0

gần như! Ồ, có vẻ như đây là câu trả lời. –

+2

Có * hai phương thức indexOf, một phương thức lấy một phần tử và một tham số là một biến vị ngữ. '[" x "," y "," z "," a "," b "," c "]. indexOf (" a ")' biên dịch không có vấn đề gì. –

+0

@MartinR, nhưng đây không phải là từ điển, ít nhất. –

Các vấn đề liên quan