我想在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
答案 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
来提供它们的生成器,所以很可能就是这种情况)。但我不认为它被记录为保证,因此可以考虑如果。