- A+

Consider the following tow sorted arrays:

`let arr1 = [1, 7, 17, 25, 38] let arr2 = [2, 5, 17, 29, 31] `

simply, the expected result should be:

`[1, 2, 5, 7, 17, 17, 25, 29, 31, 38] `

In fact, if we tried to do a simple research for this issue, we will find many resources provide the following "typical" approach:

`func mergedArrays(_ array1: [Int], _ array2: [Int]) -> [Int] { var result = [Int]() var i = 0 var j = 0 while i < array1.count && j < array2.count { if array1[i] < array2[j] { result.append(array1[i]) i += 1 } else { result.append(array2[j]) j += 1 } } while i < array1.count { result.append(array1[i]) i += 1 } while j < array2.count { result.append(array2[j]) j += 1 } return result } `

therefore:

`let merged = mergedArrays(arr1, arr2) // [1, 2, 5, 7, 17, 17, 25, 29, 31, 38] `

which is perfectly workable.

**However, my question is:**

What would it be if we tried to achieve it with more "Swifty" shorthanded solution?

*Note* that doing it as:

`let merged = Array(arr1 + arr2).sorted() `

would not be so clever, because it should be done as `O(n)`

.

I'm not sure what you mean by "more 'Swifty'", but here goes.

I would write the function like the following. It's not shorter, but much more generic: you can merge any two `Sequence`

s, as long as they have the same `Element`

type and `Element`

is `Comparable`

:

`/// Merges two sequences into one where the elements are ordered according to `Comparable`. /// /// - Precondition: the input sequences must be sorted according to `Comparable`. func merged<S1, S2>(_ left: S1, _ right: S2) -> [S1.Element] where S1: Sequence, S2: Sequence, S1.Element == S2.Element, S1.Element: Comparable { var leftIterator = left.makeIterator() var rightIterator = right.makeIterator() var merged: [S1.Element] = [] merged.reserveCapacity(left.underestimatedCount + right.underestimatedCount) var leftElement = leftIterator.next() var rightElement = rightIterator.next() loop: while true { switch (leftElement, rightElement) { case (let l?, let r?) where l <= r: merged.append(l) leftElement = leftIterator.next() case (let l?, nil): merged.append(l) leftElement = leftIterator.next() case (_, let r?): merged.append(r) rightElement = rightIterator.next() case (nil, nil): break loop } } return merged } `

Another interesting enhancement would be to make the sequence lazy, i.e. define a `MergedSequence`

and accompanying iterator struct that stores the base sequences and produces the next element on demand. This would be similar to what many functions in the standard library do, e.g. `zip`

or `Sequence.joined`

. (If you don't want to define a new type, you can also return an `AnySequence<S1.Element>`

.)