Swift Collection低估了使用量

时间:2016-10-20 11:12:44

标签: ios swift collections

Collection def merge(a, b): if type(a) is str: return { 'a': a, 'b': b } else: for key in a: a[key] = merge(a[key], b[key]) return a 的用例是什么? Documentation表示它与标准集合count具有相同的复杂性。

我已经看过它的声明:

underestimateCount

但它并没有告诉我什么时候应该使用它以及出于什么原因。

2 个答案:

答案 0 :(得分:7)

underestimatedCount实际上是Sequence协议的要求,a default implementation只返回0

public var underestimatedCount: Int {
  return 0
}

但是,对于提供自己underestimatedCount实现的序列,这对于需要序列长度下限的逻辑非常有用,而不必迭代它(请记住{{1} }并不保证非破坏性迭代。)

例如,Sequencesee its implementation here)上的map(_:)方法使用Sequence来保留结果数组的初始容量:

underestimateCount

这允许 public func map<T>( _ transform: (Iterator.Element) throws -> T ) rethrows -> [T] { let initialCapacity = underestimatedCount var result = ContiguousArray<T>() result.reserveCapacity(initialCapacity) // ... 最小化重复附加到map(_:)的成本,因为已经(可能)已经为其分配了初始内存块(尽管在任何情况下值得注意{ {1}}具有指数增长策略,可以分摊追加成本。)

但是,对于resultContiguousArray的{​​{1}}实际上只会返回集合Collection

underestimateCount

对于符合count的集合,这将是O(1)操作,否则为O(n)。

因此,由于此默认实现,直接使用public var underestimatedCount: Int { // TODO: swift-3-indexing-model - review the following return numericCast(count) } &#39; RandomAccessCollection绝对不如使用Collection&#39; s,{{{ 1}}保证非破坏性迭代,在大多数情况下underestimatedCount只会返回Sequence

虽然,当然,自定义集合类型可以提供自己的Collection实现 - 给出它们包含的元素数量的下限,以可能比underestimatedCount实现更有效的方式,可能有用。

答案 1 :(得分:2)

(因为我建议的重复目标有些过时)

在Swift 3中,方法underestimateCount()已被计算属性underestimatedCount取代。我们可以查看implementation of the latter for Collection的源代码:

  /// A value less than or equal to the number of elements in the collection.
  ///
  /// - Complexity: O(1) if the collection conforms to
  ///   `RandomAccessCollection`; otherwise, O(*n*), where *n* is the length
  ///   of the collection.
  public var underestimatedCount: Int {
    // TODO: swift-3-indexing-model - review the following
    return numericCast(count)
  }

  /// The number of elements in the collection.
  ///
  /// - Complexity: O(1) if the collection conforms to
  ///   `RandomAccessCollection`; otherwise, O(*n*), where *n* is the length
  ///   of the collection.
  public var count: IndexDistance {
    return distance(from: startIndex, to: endIndex)
  }

很明显underestimatedCount只使用count来表示符合Collection的类型(除非这些类型实现了自己的underestimatedCount版本)。