为了账号安全,请及时绑定邮箱和手机立即绑定

数组扩展以按值删除对象

数组扩展以按值删除对象

明月笑刀无情 2019-07-01 09:59:00
数组扩展以按值删除对象extension Array {     func removeObject<T where T : Equatable>(object: T) {         var index = find(self, object)         self.removeAtIndex(index)     }}但是,我在var index = find(self, object)不可转换为“T”我还尝试使用此方法签名:func removeObject(object: AnyObject)然而,我也得到了同样的错误:‘AnyObject’不可转换为‘T’做这件事的正确方法是什么?
查看完整描述

3 回答

?
ABOUTYOU

TA贡献1812条经验 获得超5个赞

截至SWIFT 2,这可以通过协议扩展方法removeObject()的所有类型上定义为一个方法。RangeReplaceableCollectionType(特别是在Array)如果集合的元素是Equatable:

extension RangeReplaceableCollectionType where Generator.Element : Equatable {

    // Remove first collection element that is equal to the given `object`:    mutating func removeObject(object : Generator.Element) {
        if let index = self.indexOf(object) {
            self.removeAtIndex(index)
        }
    }}

例子:

var ar = [1, 2, 3, 2]ar.removeObject(2)print(ar) // [1, 3, 2]

更新为SWIFT 2/Xcode 7 beta 2:正如空速度在注释中所注意到的,现在实际上可以在对模板有更多限制的泛型类型上编写一个方法,因此该方法现在实际上可以定义为Array:

extension Array where Element : Equatable {

    // ... same method as above ...}

协议扩展仍然具有适用于较大类型集的优点。

更新为SWIFT 3:

extension Array where Element: Equatable {

    // Remove first collection element that is equal to the given `object`:    mutating func remove(object: Element) {
        if let index = index(of: object) {
            remove(at: index)
        }
    }}


查看完整回答
反对 回复 2019-07-01
?
波斯汪

TA贡献1811条经验 获得超4个赞

不能在对模板有更多限制的泛型类型上编写方法。

:从SWIFT2.0开始,您现在可以编写以下方法对模板有更严格的限制。如果您已经将代码升级到2.0,请参阅其他答案,以获得使用扩展实现此功能的新选项。

你得到错误的原因'T' is not convertible to 'T'实际上是在定义新的方法中的T与原始T完全无关,如果您想在您的方法中使用T,您可以这样做,而无需在您的方法上指定它。

第二个错误的原因'AnyObject' is not convertible to 'T'T的所有可能值并不都是类。对于要转换为AnyObject的实例,它必须是类(不能是struct、enum等)。

最好的方法是使它成为接受数组作为参数的函数:

func removeObject<T : Equatable>(object: T, inout fromArray array: [T]) {}

或者,您可以通过返回一个副本来使您的方法更安全和更可重用,而不是修改原始数组:

func arrayRemovingObject<T : Equatable>(object: T, fromArray array: [T]) -> [T] {}

作为我不推荐的另一种选择,如果存储在数组中的类型不能转换为方法模板(这是可等价物),则可以让方法以静默方式失败。(为了清晰起见,我使用的是U而不是T作为方法的模板):

extension Array {
    mutating func removeObject<U: Equatable>(object: U) {
        var index: Int?
        for (idx, objectToCompare) in enumerate(self) {
            if let to = objectToCompare as? U {
                if object == to {
                    index = idx                }
            }
        }

        if(index != nil) {
            self.removeAtIndex(index!)
        }
    }}var list = [1,2,3]list.removeObject(2) // Successfully removes 2 because types matchedlist.removeObject("3") // fails silently to remove anything because the types don't matchlist // [1, 3]

编辑为了克服沉默的失败,你可以把成功当作一个嘘声:

extension Array {
  mutating func removeObject<U: Equatable>(object: U) -> Bool {
    for (idx, objectToCompare) in self.enumerate() {  //in old swift use enumerate(self) 
      if let to = objectToCompare as? U {
        if object == to {
          self.removeAtIndex(idx)
          return true
        }
      }
    }
    return false
  }}var list = [1,2,3,2]list.removeObject(2)list
list.removeObject(2)list


查看完整回答
反对 回复 2019-07-01
?
Smart猫小萌

TA贡献1911条经验 获得超7个赞

简明扼要:

func removeObject<T : Equatable>(object: T, inout fromArray array: [T]) {
    var index = find(array, object)
    array.removeAtIndex(index!)}


查看完整回答
反对 回复 2019-07-01
  • 3 回答
  • 0 关注
  • 557 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信