具有相等元素的数组的快速扩展无法调用索引(of :) [英] Swift Extension of Array with Equatable Elements Cannot Call Index(of:)

查看:106
本文介绍了具有相等元素的数组的快速扩展无法调用索引(of :)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在Swift中将扩展添加到Array类型,但仅限于其元素符合等价协议的Arrays.我正在尝试通过以下方式定义函数:

I am attempting to add an extension to the Array type in Swift limited to Arrays whose elements conform to the equatable protocol. I am attempting to define a function in the following manner:

import Foundation

extension Array where Iterator.Element: Equatable {

    func deletedIndicies<T: Equatable>(newArray: [T]) -> [Int] {

        var indicies = [Int]()

        for element in self {

              if newArray.index(of: element) == nil {

                     indicies.append(self.index(of: element)!)
              }
        }

        return indicies
        }
    }
}

该函数的目的是返回原始数组中未出现在newArray中的所有项目的索引.

The purpose of the function is to return the indices of any items in the original array that do not appear in the newArray.

我在Xcode中收到的错误是:无法使用类型为((of:Element)'的参数列表调用'index'

The error I receive in Xcode is: Cannot invoke 'index' with an argument list of type '(of: Element)'

由于我只为元素可等于的数组定义函数,并且要求newArray的元素可等于,所以我不确定为什么不能调用index方法.

Since I am defining the function for only Arrays whose elements are equatable and am requiring that the elements of the newArray are equatable, I am unsure why I cannot invoke the index method.

推荐答案

问题是您在方法中定义了一个新的通用占位符T –不一定与Element相同.因此,当您说newArray.index(of: element)时,您试图将Element传递给类型为T的参数.

The problem is you're defining a new generic placeholder T in your method – which is not necessarily the same type as Element. Therefore when you say newArray.index(of: element), you're trying to pass an Element into a argument of type T.

因此,解决方案是简单地将newArray:参数键入为[Element]:

The solution therefore is to simply to type the newArray: parameter as [Element]:

extension Array where Element : Equatable {
    func deletedIndicies(byKeeping elementsToKeep: [Element]) -> [Int] {
        // ...
    }
}

请注意,此方法也可以实现为:

As a side note, this method could also be implemented as:

extension Array where Element : Equatable {

    func deletedIndicies(byKeeping elementsToKeep: [Element]) -> [Int] {

        // use flatMap(_:) to iterate over a sequence of pairs of elements with indices,
        // returning the index of the element, if elementsToKeep doesn't contains it,
        // or nil otherwise, in which case flatMap(_:) will filter it out.
        return self.enumerated().flatMap {
            elementsToKeep.contains($1) ? nil : $0
        }
    }
}

此外,如果将Element的约束更改为Hashable,则也可以在O(n)而不是O(n * m)的时间内实现,这可能是希望的:

Also, if you change the constraint on Element to Hashable, this could be also be implemented in O(n), rather than O(n * m) time, which could potentially be desirable:

extension Array where Element : Hashable {

    func deletedIndicies(byKeeping elementsToKeep: [Element]) -> [Int] {

        // create new set of elements to keep.
        let setOfElementsToKeep = Set(elementsToKeep)

        return self.enumerated().flatMap {
            setOfElementsToKeep.contains($1) ? nil : $0
        }
    }
}

这篇关于具有相等元素的数组的快速扩展无法调用索引(of :)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆