'Swift 5 - Two Arrays together in one by selecting every nth from one
actually i'm learning swift with Xcode 11.3.1 to build apps.
I got a question for working with arrays.
I have two arrays and want to combine both by selecting most of values from array one and every nth from array two. Example:
let arr1 = ["Value 1", "Value 2", "Value 3" "Value 4", "Value 5", "Value 6"]
let arr2 = ["Insert 1", "Insert 2", "Insert 3"]
Output should be: Value 1, Value 2, Insert 1, Value 3, Value 4, Insert 2 ...
If arr1 is ended append the last values from arr2 at the end and of course the other way around.
I can put the two arrays together and .shuffle() them but that's not what I finally want.
Hope someone can give a hint or a solution.
PS: In JS I know I can user methods like .reduce and push with using the modulator-operator but this is not JS ;-)
Kind regards, Steven
Solution 1:[1]
I would highly recommend using Apple's swift-algorithms package, which makes this really easy.
import Algorithms
let arr1 = ["Value 1", "Value 2", "Value 3", "Value 4", "Value 5", "Value 6"]
let arr2 = ["Insert 1", "Insert 2", "Insert 3"]
result = zip(arr1.chunks(ofCount: 2), arr2.chunks(ofCount: 1)).flatMap(+)
print(result)
Here is it expanded out, to illustrate how this works:
import Algorithms
let arr1 = ["Value 1", "Value 2", "Value 3", "Value 4", "Value 5", "Value 6"]
let arr2 = ["Insert 1", "Insert 2", "Insert 3"]
let arr1Chunks = arr1.chunks(ofCount: 2) // [["Value 1", "Value 2"], ["Value 3", "Value 4"], ["Value 5", "Value 6"]]
let arr2Chunks = arr2.chunks(ofCount: 1) // [["Insert 1"], ["Insert 2"], ["Insert 3"]]
let zipped = zip(arr1.chunks(ofCount: 2), arr2.chunks(ofCount: 1) // [(["Value 1", "Value 2"], ["Insert 1"]), (["Value 3", "Value 4"], ["Insert 2"]), (["Value 5", "Value 6"], ["Insert 3"])
let result = zipped.flatMap { left, right in left + right }
Technically the use of .chunks(ofCount: 1) is a bit unnecessary, but this makes it really easy to tune how many elements of arr2 you want to insert between every chunk of elements of arr1. It could instead be written with:
zip(arr1.chunks(ofCount: 2), arr2).flatMap { $0 + [$1] }
But I find this less clear, tbh.
Solution 2:[2]
Updated Code : -
I Gave it a try and able to genreate result as below : -
Result Array = ["Value 1", "Value 2", "Value 3", "Insert 1", "Value 4", "Value 5", "Value 6", "Insert 2", "Value 7", "Value 8", "Value 9", "Insert 3", "Insert 5", "Insert 6"]
The Code I used is as following : -
let arr1 = ["Value 1", "Value 2", "Value 3", "Value 4", "Value 5", "Value 6", "Value 7", "Value 8", "Value 9"]
let arr2 = ["Insert 1", "Insert 2", "Insert 3", "Insert 5", "Insert 6"]
var arrayResult : [String] = []
let totallength = arr1.count + arr2.count
let intervalCount = 4
var count = 0
for i in 1...totallength {
if count < arr2.count {
if i % intervalCount == 0 {
arrayResult.append(arr2[count])
count += 1
} else {
if i - count - 1 < arr1.count {
arrayResult.append(arr1[i - count - 1])
} else {
arrayResult.append(arr2[count])
count += 1
}
}
} else {
arrayResult.append(arr1[i - count - 1])
}
}
print("Result Array = \(arrayResult)")
Hope you found it useful.
Solution 3:[3]
Reduce might be a good option. Just an example from swift, not optimal in performance, but I think it´s readable what it does.
arr2.reduce([]) { partialResult, value in
partialResult += [wordArray.removeFirst(), wordArray.removeFirst(), value]
}
If you don't want crashed on missing values in arr1
var reversed: [Any] = arr1.reversed()
let combine = arr2.reduce(into: []) { partialResult, value in
partialResult += [reversed.popLast(), reversed.popLast(), value]
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Alexander |
| Solution 2 | |
| Solution 3 |
