Swift:在使用filter函数进行过滤后,调用indexOf时无法将类型的值转换为@noescape

时间:2021-07-13 10:10:40

In Swift 2, I'm receiving an error:

在Swift 2中,我收到一个错误:

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

无法将'[String:AnyObject]'类型的值转换为预期的参数类型'@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
}

What I'm doing wrong? I can't understand. :/

我做错了什么?我无法理解。 :/

My aim, is to find index of that item, I think that I open for alternative solutions, but of course this one is preferred, because I think this is the "right way".

我的目标是找到那个项目的索引,我认为我开放替代解决方案,但当然这个是首选,因为我认为这是“正确的方法”。

1 个解决方案

#1


26  

The indexOf method on Swift arrays does not take an object of a type matching the array's type. Instead, it takes a closure. That closure takes an element of the array's type and returns a bool.

Swift数组上的indexOf方法不接受与数组类型匹配的类型的对象。相反,它需要关闭。该闭包采用数组类型的元素并返回bool。

So, in fact, we don't (and shouldn't) even bother with the filter call unless we actually need the resultant array. If we're just looking for the first object that passes whatever test you are filtering for... well we just pass that exact same test to indexOf.

所以,实际上,除非我们确实需要结果数组,否则我们不会(也不应该)对过滤器调用感到烦恼。如果我们只是寻找通过你正在过滤的任何测试的第一个对象......那么我们只需将完全相同的测试传递给indexOf。

So, to keep things simple, if we have an array of strings (and let's say they're all single letter strings with lots of repetition), and I want to find the first index of the string "a", rather than filtering the array down to strings that are "a", then finding the first string that passed that test with the first method, and then finding the index of that exact object, instead, I just pass that test into the indexOf method:

所以,为了简单起见,如果我们有一个字符串数组(并且假设它们都是具有大量重复的单字母字符串),并且我想找到字符串“a”的第一个索引,而不是过滤将数组向下转换为“a”的字符串,然后找到第一个使用第一个方法传递该测试的字符串,然后找到该确切对象的索引,而不是将该测试传递给indexOf方法:

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

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

For clarity, it appears that simply passing an individual element and looking for that does work in some cases. It probably relies on conformance to Swift's Equatable protocol. I could for example have simplied used letters.indexOf("a") here. The compiler would have been happy. But obviously, not every array is composed required to hold things that conform to Equatable, and the array can't make assumptions about how to compare its elements then. In these cases, you will have to use the above example of passing a closure. It's probably worth noting that passing this closure to indexOf rather than first filtering and then calling indexOf is going to be egregiously more efficient anyway, even if your array allows the letters.indexOf("a") approach. If for example, I had more complex strings, and I just wanted the first string that started with the letter 'a', this would be far, far more efficient than starting by filtering down the original array to an array of strings starting with 'a'.

为清楚起见,似乎只是简单地传递单个元素并在某些情况下查找它。它可能依赖于Swift的Equatable协议的一致性。我可以在这里简单地使用letters.indexOf(“a”)。编译器会很高兴。但显然,并不是每个数组都需要保存符合Equatable的东西,并且数组不能对如何比较其元素做出假设。在这些情况下,您将不得不使用上面传递闭包的示例。值得注意的是,即使您的数组允许使用letters.indexOf(“a”)方法,将此闭包传递给indexOf而不是先进行过滤然后调用indexOf也会非常有效。例如,如果我有更复杂的字符串,并且我只想要以字母'a'开头的第一个字符串,这将比通过将原始数组过滤到以'开头'开头的字符串数组开始更有效率。一个'。

#1


26  

The indexOf method on Swift arrays does not take an object of a type matching the array's type. Instead, it takes a closure. That closure takes an element of the array's type and returns a bool.

Swift数组上的indexOf方法不接受与数组类型匹配的类型的对象。相反,它需要关闭。该闭包采用数组类型的元素并返回bool。

So, in fact, we don't (and shouldn't) even bother with the filter call unless we actually need the resultant array. If we're just looking for the first object that passes whatever test you are filtering for... well we just pass that exact same test to indexOf.

所以,实际上,除非我们确实需要结果数组,否则我们不会(也不应该)对过滤器调用感到烦恼。如果我们只是寻找通过你正在过滤的任何测试的第一个对象......那么我们只需将完全相同的测试传递给indexOf。

So, to keep things simple, if we have an array of strings (and let's say they're all single letter strings with lots of repetition), and I want to find the first index of the string "a", rather than filtering the array down to strings that are "a", then finding the first string that passed that test with the first method, and then finding the index of that exact object, instead, I just pass that test into the indexOf method:

所以,为了简单起见,如果我们有一个字符串数组(并且假设它们都是具有大量重复的单字母字符串),并且我想找到字符串“a”的第一个索引,而不是过滤将数组向下转换为“a”的字符串,然后找到第一个使用第一个方法传递该测试的字符串,然后找到该确切对象的索引,而不是将该测试传递给indexOf方法:

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

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

For clarity, it appears that simply passing an individual element and looking for that does work in some cases. It probably relies on conformance to Swift's Equatable protocol. I could for example have simplied used letters.indexOf("a") here. The compiler would have been happy. But obviously, not every array is composed required to hold things that conform to Equatable, and the array can't make assumptions about how to compare its elements then. In these cases, you will have to use the above example of passing a closure. It's probably worth noting that passing this closure to indexOf rather than first filtering and then calling indexOf is going to be egregiously more efficient anyway, even if your array allows the letters.indexOf("a") approach. If for example, I had more complex strings, and I just wanted the first string that started with the letter 'a', this would be far, far more efficient than starting by filtering down the original array to an array of strings starting with 'a'.

为清楚起见,似乎只是简单地传递单个元素并在某些情况下查找它。它可能依赖于Swift的Equatable协议的一致性。我可以在这里简单地使用letters.indexOf(“a”)。编译器会很高兴。但显然,并不是每个数组都需要保存符合Equatable的东西,并且数组不能对如何比较其元素做出假设。在这些情况下,您将不得不使用上面传递闭包的示例。值得注意的是,即使您的数组允许使用letters.indexOf(“a”)方法,将此闭包传递给indexOf而不是先进行过滤然后调用indexOf也会非常有效。例如,如果我有更复杂的字符串,并且我只想要以字母'a'开头的第一个字符串,这将比通过将原始数组过滤到以'开头'开头的字符串数组开始更有效率。一个'。