CollectionTypes上的Swift“ - ”二元运算符

时间:2015-07-21 15:53:59

标签: arrays swift

我想只在对象包含在另一个数组中时才删除数组中的对象。

myArray = myArray - otherArray

如何将此行为添加为CollectionType

的扩展名

2 个答案:

答案 0 :(得分:2)

所以你可以做几件事。我已经要求这些版本中的元素是可散列的,但是这些方法与它们相似(如果慢得多)只是为了等同。

如果您的收藏符合RangeReplaceableCollectionType,那么它可以使用removeAtIndex方法。这意味着您可以返回与给定类型相同的集合:

extension RangeReplaceableCollectionType where Generator.Element : Hashable {
  mutating func subtractInPlace(vals: Set<Generator.Element>) {
    // The indices need to be reversed, because removing at a given index invalidates all
    // those above it
    for idx in indices.reverse()
      where vals.contains(self[idx]) { // This is why hashable is a requirement: the 
      removeAtIndex(idx)               // contains method is much more efficient on sets
    }
  }
  mutating func subtractInPlace<
    S : SequenceType where
    S.Generator.Element == Generator.Element
    >(seq: S) {
      subtractInPlace(Set(seq))
  }
  func subtract(vals: Set<Generator.Element>) -> Self {
    var col = self
    col.subtractInPlace(vals)
    return col
  }
  func subtract<S : SequenceType where S.Generator.Element == Generator.Element>(seq: S) -> Self {
    return subtract(Set(seq))
  }
}

否则,你只需返回一个数组。 (实际上,我认为这种方法更快)

extension SequenceType where Generator.Element : Hashable {
  func subtract(vals: Set<Generator.Element>) -> [Generator.Element] {
    return filter { !vals.contains($0) }
  }
  func subtract<
    S : SequenceType where
    S.Generator.Element == Generator.Element
    >(seq: S) -> [Generator.Element] {
      return subtract(Set(seq))
  }
}

然后,您需要定义运算符。这里有这么多不同版本的原因是Swift将在每种情况下选择最具体的实现。因此,在转换为集合的版本之前,将选择具有集合的版本。这使您可以实现高效的实现,而不会使其他效率较低的实现失效。

func - <
  C : RangeReplaceableCollectionType where
  C.Generator.Element : Hashable
  >(lhs: C, rhs: Set<C.Generator.Element>) -> C {
    return lhs.subtract(rhs)
}

func - <
  C : RangeReplaceableCollectionType,
  S : SequenceType, T : Hashable where
  C.Generator.Element == T,
  S.Generator.Element == T
  >(lhs: C, rhs: S) -> C {
    return lhs.subtract(rhs)
}

func - <
  S : SequenceType where
  S.Generator.Element : Hashable
  >(lhs: S, rhs: Set<S.Generator.Element>) -> [S.Generator.Element] {
    return lhs.subtract(rhs)
}

func - <
  S0 : SequenceType,
  S1 : SequenceType,
  T : Hashable where
  S0.Generator.Element == T,
  S1.Generator.Element == T
  >(lhs: S0, rhs: S1) -> [T] {
    return lhs.subtract(rhs)
}

答案 1 :(得分:-1)

用两个操作数写一个全局函数“func - ”。尝试将其作为通用功能。