Reputation: 4311
I want to implement function in Swift similar to default find
, but which accept comparator:
func find<C : CollectionType>(domain: C, comparator: (C.Generator.Element) -> Bool) -> C.Index? {
for (index, element) in enumerate(domain) {
if comparator(element) {
return index
}
}
return nil
}
The problem that enumerate
returns tuple of type (Int, C.Generator.Element)
, while i need (C.Index, C.Generator.Element)
. I have searched much, but didn't find how to iterate using C.Index
type.
Edit.
Sorry, it was a typo. I mean enumerate
instead of generate
Upvotes: 2
Views: 211
Reputation: 40973
The easiest solution is to use indices
rather than enumerate
, then use subscript to fetch the value:
func find<C : CollectionType>(domain: C, comparator: (C.Generator.Element) -> Bool) -> C.Index? {
for index in indices(domain) {
if comparator(domain[index]) {
return index
}
}
return nil
}
but I'm guessing you already knew that and wanted a solution that got you both the element and the index together without needing subscript. You could use Zip2
to do this:
func find<C : CollectionType>(domain: C, comparator: (C.Generator.Element) -> Bool) -> C.Index? {
for (index, element) in Zip2(indices(domain), domain) {
if comparator(element) {
return index
}
}
return nil
}
edit: as Rob points out below, this is guaranteed to work per the swift docs.
However this relies on something that makes me slightly uneasy, which is assuming that iterating over a collection via it's generator is guaranteed to return values in the same order as they are indexed. It would possibly be a slightly obnoxious thing for a collection to not do this (and since most collections use IndexingGenerator
to serve up their generators, it's very likely to be the case). But I don't think it's documented as a guarantee so could be considered iffy.
Upvotes: 2
Reputation: 299703
As Airspeed Velocity notes, I assume you mean enumerate
here rather than generate
. The tool you want, however, is indices
to get all the indices of the collection:
func find<C : CollectionType>(domain: C, comparator: (C.Generator.Element) -> Bool) -> C.Index? {
for index in indices(domain) {
if comparator(domain[index]) {
return index
}
}
return nil
}
Upvotes: 2