我有一大堆对象,并希望将它分成两个包含交替顺序对象的数组.
例:
[0,1,2,3,4,5,6]
变成这两个数组(它们应该交替)
[0,6]和[1,5]
分割阵列有很多种方法.但是,如果阵列很大,那么最有效(成本最低)的是什么.
使用过滤器有各种奇特的方法,但大多数可能需要两次传递而不是一次,所以你也可以只使用for循环.
在这种情况下预留空间可能会产生很大的不同,因为如果源很大,它将避免在新阵列增长时不必要的重新分配,并且所需空间的计算在阵列上是恒定的时间.
- // could make this take a more generic random-access collection source
- // if needed,or just make it an array extension instead
- func splitAlternating<T>(source: [T]) -> ([T],[T]) {
- var evens: [T] = [],odds: [T] = []
- evens.reserveCapacity(source.count / 2 + 1)
- odds.reserveCapacity(source.count / 2)
- for idx in indices(source) {
- if idx % 2 == 0 {
- evens.append(source[idx])
- }
- else {
- odds.append(source[idx])
- }
- }
- return (evens,odds)
- }
- let a = [0,6]
- splitAlternating(a) // ([0,6],[1,5])
如果性能真的很重要,可以使用source.withUnsafeBufferPointer来访问源元素,以避免索引边界检查.
如果数组真的很大,并且除了采样少量元素之外你不打算使用结果数据,你可以考虑使用一个惰性视图(尽管std lib lazy filter在这里用得不多,因为它返回序列而不是集合 – 您可能需要编写自己的集合.