How do I insert an item repeatedly between every two elements of an array?

Here is the original answer converted to Swift 3/4

let items = [1, 2, 3]
let sep = 0

let newItems = Array(items.map { [$0] }.joined(separator: [sep]))

print(newItems) // [1, 0, 2, 0, 3]

converted to swift 5

extension Array {

  func insert(separator: Element) -> [Element] {
    (0 ..< 2 * count - 1).map { $0 % 2 == 0 ? self[$0/2] : separator }
  }
}

(Note: The answer has been updated for Swift 3 and later with the help of Brandon's answer and ober's answer).

This does the trick:

let items = [1, 2, 3]
let sep = 0

let newItems = Array(items.map { [$0] }.joined(separator: [sep]))
print(newItems) // [1, 0, 2, 0, 3]

items.map { [ $0 ] } creates an array of single-element arrays, and joined(separator: [sep]) then interposes the separator and concatenates the elements. The result is a JoinedSequence from which we can create an Array.

As it turns out (benchmarks below) it is quite expensive to create many temporary arrays. This can be avoided by using “single-element collections”:

let newItems = Array(items.map(CollectionOfOne.init).joined(separator: CollectionOfOne(sep)))

Another possible solution is

let newItems = (0 ..< 2 * items.count - 1).map { $0 % 2 == 0 ? items[$0/2] : sep }

which maps even indices to the corresponding element of items, and odd indices to the separator. This turns out to be the fastest solution for large arrays.

Benchmark: With items containing 1,000,000 elements, compiled in Release mode on a 2.3 GHz Intel Core i7 MacBook Pro, I measured the following approximate execution times:

  • First method (map + joined with arrays): 0.28 seconds.

  • Second method (map + joined with CollectionOfOne): 0.035 seconds.

  • Third method (using only map): 0.015 seconds.