关于数组:CollectionTypes上的快速”-“二元运算符

Swift “-” Binary Operator on CollectionTypes

仅当对象包含在另一个数组中时,我才希望删除该对象。

1
myArray = myArray - otherArray

如何将这种行为添加为CollectionType的扩展


因此,您可以通过多种方式进行操作。我已经要求这些版本中的元素是可散列的,但要使它们相等,该方法将是相似的(如果要慢得多)。

如果您的集合符合RangeReplaceableCollectionType,则它具有removeAtIndex方法可用。这意味着您可以返回与给定类型相同的集合:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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))
  }
}

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

1
2
3
4
5
6
7
8
9
10
11
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将在每种情况下选择最具体的实现。因此,将在转换为集合的版本之前选择具有集合的版本。这使您可以有一个有效的实现,而不会使其他效率较低的实现无效。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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)
}


只需编写一个带有两个操作数的全局函数" func-"。尝试将其作为通用函数来执行。