How can I interleave two arrays?

醉酒当歌 提交于 2019-11-27 09:26:59

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() enumerates the 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 the arrays can have different length then you append the extra elements of the 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)
}

If you're just looking to interleave two arrays, you could 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

With Swift 5, you can use one of the following Playground sample codes in order to solve your problem.


#1. Using zip(_:_:) function and Collection's flatMap(_:) method

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 different lengths, the resulting sequence is the same length as the shorter sequence.


#2. Using 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's 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]

As an alternative, you can wrap your iterators inside a 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]
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!