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