简体   繁体   中英

Swift: iterate using Index and Element

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

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
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM