I have this code:
let items = [1, 2, 3] let sep = 0 I want to insert sep between every two elements of items to get a result similar to this:
newItems = [1, 0, 2, 0, 3] Is there a concise way to do this through functional programming in Swift? Something similar to String.join(), but for arrays.
map the original array to another array by taking the first two elements of each subarray and concatenating them together, then building a new subarray by adding the rest of the elements (which we get with the rest parameter during the array destructuring) to a new array that contains the joined string.
(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.
converted to swift 5
extension Array { func insert(separator: Element) -> [Element] { (0 ..< 2 * count - 1).map { $0 % 2 == 0 ? self[$0/2] : separator } } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With