There are various fancy ways to do this with a filter, but most of them will probably require two passes, not one, so you can just use a for-loop.
Reserving space forward can be of great importance in this case, because if the source is large, it will avoid unnecessary redistribution as new arrays grow, and calculating the required space at constant time on arrays.
// 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,1,2,3,4,5,6] splitAlternating(a) // ([0, 2, 4, 6], [1, 3, 5])
If performance is really important, you can use source.withUnsafeBufferPointer to access the source elements to avoid checking the bounds of the index.
If the arrays are really huge, and you are not going to use the data, except as an example of a small number of elements, you can use the lazy representation instead (although the std lib lazy filter is not very useful here, since it returns a sequence, not a collection - maybe you you will need to write your own).