Swift Fun with ArraySlice

There is a lovely article by Luna An describing ArraySlice objects in more detail than I do here. It covers Swift 3 at the moment, and you should note that Swift 4 includes support for single-ended ranges, so you can create slices ala [..<count].

I found a good use for an ArraySlice while trying to find quartiles in a set of data.

The problem of finding each quartile is essentially the same problem of finding the median from three different data sets, one being the original input set, the other two being the upper and lower half of the set after removing the original median element, if it exists.

Here, I use findMedian to perform all three tasks. I found that I had to do a bit of extra work because the array slice is not indexed starting at zero. I wonder why they chose to implement slices in this way?

import Foundation

func findMedian(_ data: ArraySlice<Int>) -> (Int, Int, Int) {
    let index1 = (data.count-1)/2
    let index2 = data.count/2
    let sliceIndex1 = index1 + data.startIndex
    let sliceIndex2 = index2 + data.startIndex
    let median = (data[sliceIndex1]+data[sliceIndex2])/2
    return (sliceIndex1, sliceIndex2, median)
}

let data = [0, 1, 2, 5, 11, 17, 19, 21]

let X = data[0..<data.count]
let (q2Index1, q2Index2, Q2) = findMedian(X)
let L = data[0..<q2Index2]
let U = data[(q2Index1+1)..<data.count]
let (_, _, Q1) = findMedian(L)
let (_, _, Q3) = findMedian(U)

print(Q1)
print(Q2)
print(Q3)