如何获取符合 `Sequence` 类型的计数?
How to get the count of a type conforming to `Sequence`?
假设我有这个代码:
func work<S: Sequence>(sequence: S) {
// do stuff
}
我怎么知道 sequence
中有多少个元素?
我想要的明显版本效率很低:
var count = 0
for element in sequence {
count += 1
}
一定有更好的方法吧?
我认为对于符合以下条件的 任意 类型没有更好的方法
SequenceType
。关于序列的唯一已知信息是
有一个 generate()
方法 returning 一个 GeneratorType
,这反过来
有一个 next()
方法。 next()
方法前进到下一个
序列的元素和 returns 它,或者 returns nil
如果有
没有下一个元素。
请注意,根本不需要 next()
最终 returns
nil
:一个序列可能有 "infinite" 个元素。
因此,枚举序列是统计其数量的唯一方法
元素。但这不必终止。因此答案可以
也可以是:接受序列参数的函数不需要知道
元素总数。
对于符合 CollectionType
的类型,您可以使用
countElements()
函数(在 Swift 1.2 中重命名为 count()
)。
还有underestimateCount()
:
/// Return an underestimate of the number of elements in the given
/// sequence, without consuming the sequence. For Sequences that are
/// actually Collections, this will return countElements(x)
func underestimateCount<T : SequenceType>(x: T) -> Int
但这不一定是 return 元素的确切数量。
更 "functional" 的方法是:
let count = sequence.reduce(0) { acc, row in acc + 1 }
甚至进行扩展:
extension Sequence {
var count: Int { return reduce(0) { acc, row in acc + 1 } }
}
let count = sequence.count
注意这仍然存在基本的序列问题,您必须使用序列来计算它。
假设我有这个代码:
func work<S: Sequence>(sequence: S) {
// do stuff
}
我怎么知道 sequence
中有多少个元素?
我想要的明显版本效率很低:
var count = 0
for element in sequence {
count += 1
}
一定有更好的方法吧?
我认为对于符合以下条件的 任意 类型没有更好的方法
SequenceType
。关于序列的唯一已知信息是
有一个 generate()
方法 returning 一个 GeneratorType
,这反过来
有一个 next()
方法。 next()
方法前进到下一个
序列的元素和 returns 它,或者 returns nil
如果有
没有下一个元素。
请注意,根本不需要 next()
最终 returns
nil
:一个序列可能有 "infinite" 个元素。
因此,枚举序列是统计其数量的唯一方法 元素。但这不必终止。因此答案可以 也可以是:接受序列参数的函数不需要知道 元素总数。
对于符合 CollectionType
的类型,您可以使用
countElements()
函数(在 Swift 1.2 中重命名为 count()
)。
还有underestimateCount()
:
/// Return an underestimate of the number of elements in the given
/// sequence, without consuming the sequence. For Sequences that are
/// actually Collections, this will return countElements(x)
func underestimateCount<T : SequenceType>(x: T) -> Int
但这不一定是 return 元素的确切数量。
更 "functional" 的方法是:
let count = sequence.reduce(0) { acc, row in acc + 1 }
甚至进行扩展:
extension Sequence {
var count: Int { return reduce(0) { acc, row in acc + 1 } }
}
let count = sequence.count
注意这仍然存在基本的序列问题,您必须使用序列来计算它。