我有一大堆对象,并希望将它分成两个包含交替顺序对象的数组.
例:
[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在这里用得不多,因为它返回序列而不是集合 – 您可能需要编写自己的集合.