Here is another possible solution:
let evenA = stride(from: 0, to: masterA.count, by: 2).map { masterA[$0] } let oddA = stride(from: 1, to: masterA.count, by: 2).map { masterA[$0] }
Elements are โselectedโ directly from odd / even positions in the original array.
Performance Comparison:
My simple, not very complicated benchmarking code:
import Swift let N = 10_000_000 let RUNS = 50 let masterA = (0..<N).map { $0 } var times = (0.0, 0.0, 0.0, 0.0) for _ in 1...RUNS { // filter+map (dfri) do { let start = Date() let evenA = masterA.enumerated().filter { $0.0 % 2 == 0 }.map{ $0.1 } let oddA = masterA.enumerated().filter { $0.0 % 2 != 0 }.map{ $0.1 } let time = Date().timeIntervalSince(start) times.0 += time } // flatMap (dfri) do { let start = Date() let evenA = masterA.enumerated().flatMap { $0 % 2 == 0 ? $1 : nil } let oddA = masterA.enumerated().flatMap { $0 % 2 != 0 ? $1 : nil } let time = Date().timeIntervalSince(start) times.1 += time } // stride+map (me) do { let start = Date() let evenA = stride(from: 0, to: masterA.count, by: 2).map { masterA[$0] } let oddA = stride(from: 1, to: masterA.count, by: 2).map { masterA[$0] } let time = Date().timeIntervalSince(start) times.2 += time } // loop (Keiwan) do { let start = Date() var evenA = [Int]() var oddA = [Int]() for (index, element) in masterA.enumerated() { if index % 2 == 0 { evenA.append(element) } else { oddA.append(element) } } let time = Date().timeIntervalSince(start) times.3 += time } } print(N, RUNS) print(times.0/Double(RUNS), times.1/Double(RUNS), times.2/Double(RUNS), times.3/Double(RUNS))
Results: (On MacBook in Release mode)
#elements filter + map flatMap stride + map loop
10,000 0.0001 0.00008 0.00004 0.00004
100,000 0.0016 0.0008 0.0004 0.0004
1,000,000 0.0295 0.0136 0.0090 0.0091
10,000,000 0.3025 0.1332 0.0909 0.1250
source share