Swift:使用Index和Element进行迭代

时间:2014-12-29 20:07:19

标签: ios macos swift

我想在Swift中实现类似于默认find的函数,但它接受比较器:

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
}

enumerate返回(Int, C.Generator.Element)类型元组的问题,而我需要(C.Index, C.Generator.Element)。我搜索了很多,但没有找到如何使用C.Index类型进行迭代。

修改

对不起,这是一个错字。我的意思是enumerate而不是generate

2 个答案:

答案 0 :(得分:2)

正如Airspeed Velocity所说,我认为你的意思是enumerate而不是generate。但是,您需要的工具indices可以获取集合的所有索引:

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
}

答案 1 :(得分:2)

最简单的解决方案是使用indices而不是enumerate,然后使用下标来获取值:

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
}

但我猜你已经知道了,并且想要一个解决方案,既可以将元素和索引放在一起,又不需要下标。您可以使用Zip2执行此操作:

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
}

编辑:正如Rob在下面指出的那样,这可以保证按照swift文档工作。

然而这依赖于让我有点不安的东西,这假设通过它的生成器迭代集合保证以与索引相同的顺序返回值。对于集合而言,这可能是一件令人讨厌的事情(并且由于大多数集合使用IndexingGenerator来提供它们的生成器,所以很可能就是这种情况)。但我不认为它被记录为保证,因此可以考虑如果。