How can I interleave two arrays?

If I have two arrays like

let one = [1,3,5] let two = [2,4,6] 

I would like to combine / interleave arrays in the following pattern [one [0], two [0], one [1], two [1], etc.].

 //prints [1,2,3,4,5,6] let comibned = mergeFunction(one, two) print(combined) 

What would be a good way to implement the join function?

 func mergeFunction(one: [T], _ two: [T]) -> [T] { var mergedArray = [T]() //What goes here return mergedArray } 
+11
source share
3 answers

If both arrays have the same length, then this is a possible solution:

 let one = [1,3,5] let two = [2,4,6] let merged = zip(one, two).flatMap { [$0, $1] } print(merged) // [1, 2, 3, 4, 5, 6] 

Here zip() lists arrays in parallel and returns a sequence of pairs (2-element tuples) with one element from each array. flatMap() creates a 2-element array from each pair and concatenates the result.

If arrays can have different lengths, you add additional elements of a longer array to the result:

 func mergeFunction<T>(one: [T], _ two: [T]) -> [T] { let commonLength = min(one.count, two.count) return zip(one, two).flatMap { [$0, $1] } + one.suffixFrom(commonLength) + two.suffixFrom(commonLength) } 

Update for Swift 3:

 func mergeFunction<T>(_ one: [T], _ two: [T]) -> [T] { let commonLength = min(one.count, two.count) return zip(one, two).flatMap { [$0, $1] } + one.suffix(from: commonLength) + two.suffix(from: commonLength) } 
+26
source

If you just want to alternate between two arrays, you can just do something like:

 let maxIndex = max(one.count, two.count) var mergedArray = Array<T>() for index in 0..<maxIndex { if index < one.count { mergedArray.append(one[index]) } if index < two.count { mergedArray.append(two[index]) } } return mergedArray 
+6
source

With Swift 5, you can use one of the following Playground code examples to solve your problem.


# 1. Using the zip(_:_:) and flatMap(_:) Collection flatMap(_:)

 let one = [1, 3, 5] let two = [2, 4, 6] let array = zip(one, two).flatMap({ [$0, $1] }) print(array) // print: [1, 2, 3, 4, 5, 6] 

Apple states :

If the two sequences passed to zip(_:_:) are of different lengths, the resulting sequence has the same length as the shorter sequence.


# 2. Using the sequence(state:next:) function

 let one = [1, 3, 5] let two = [2, 4, 6] let unfoldSequence = sequence(state: (false, one.makeIterator(), two.makeIterator()), next: { state -> Int? in state.0.toggle() return state.0 ? state.1.next() : state.2.next() }) let array = Array(unfoldSequence) print(array) // print: [1, 2, 3, 4, 5, 6] 

# 3. Using AnyIterator init(_:) initializer

 let one = [1, 3, 5] let two = [2, 4, 6] var oneIterator = one.makeIterator() var twoIterator = two.makeIterator() var state = false let anyIterator = AnyIterator<Int> { state.toggle() return state ? oneIterator.next() : twoIterator.next() } let array = Array(anyIterator) print(array) // print: [1, 2, 3, 4, 5, 6] 

Alternatively, you can wrap your iterators in an AnySequence instance:

 let one = [1, 3, 5] let two = [2, 4, 6] let anySequence = AnySequence<Int>({ () -> AnyIterator<Int> in var oneIterator = one.makeIterator() var twoIterator = two.makeIterator() var state = false return AnyIterator<Int> { state.toggle() return state ? oneIterator.next() : twoIterator.next() } }) let array = Array(anySequence) print(array) // print: [1, 2, 3, 4, 5, 6] 
0
source

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


All Articles