Separate odd and even indices in an array of sequences

A for the in loop will not work, since the int type does not match the protocol sequence.

I have 3 arrays:

1 main array in which the array is stored

1 odd array empty at the beginning

1 even array, empty at the beginning

The point is that all the odd indices of the main array will be stored in the odd array and the same for the even array.

while i < masterA.count { evenA.append(masterA[i]) if i > 0{ oddA.append(masterA[i - 1]) } i += 2 } 

However, this does not work well enough. Anyone have a better idea?

+5
source share
4 answers

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
+10
source

You can use enumerated() to get both the index and the value during the loop:

 for (index, element) in masterA.enumerated() { if index % 2 == 0 { evenA.append(element) } else { oddA.append(element) } } 

This will store every element from masterA with an odd index in oddA and every element with an even index in evenA .

+6
source

I may not understand your intentions, but it seems that you want the masterA elements with odd indices to be stored in oddA , and vice versa, masterA elements that have even indexes should be stored in evenA .

This can be done by filtering masterA wrt masterA indexes that are easily accessible from masterA.enumerated() .

 let masterA = [4, 5, 2, 1, 7, 8, 1] let evenA = masterA.enumerated().filter { $0.0 % 2 == 0 }.map{ $0.1 } let oddA = masterA.enumerated().filter { $0.0 % 2 != 0 }.map{ $0.1 } print(evenA) // [4, 2, 7, 1] print(oddA) // [5, 1, 8] 

As @Hamish points out in his comment below, we could use flatMap as an alternative to the filter and map chain.

 let evenA = masterA.enumerated().flatMap { $0 % 2 == 0 ? $1 : nil } let oddA = masterA.enumerated().flatMap { $0 % 2 != 0 ? $1 : nil } 

The last flatMap solution flatMap more compact, while the filter ... map solution probably shows the intention a little clearer. In this particular contraction and semantics competition, I personally would prefer the flatMap solution (even if I always forget it ...).

+4
source

Another solution

Swift 3.0 Code

 let array = [1,2,3,4,5,6,7,8] var oddArray = [Int]() var evenArray = [Int]() for (index,value) in array.enumerated() { if index % 2 == 0 { // It is odd because index starts from 0 in array and I am assuming the 0 index as the odd one. oddArray.append(value) } else { evenArray.append(value) } } 

Odd array = [1,3,5,7]
Even Array = [2,4,6,8]

+1
source

Source: https://habr.com/ru/post/1258043/


All Articles