Eric George
Eric George

Reputation: 246

Creating sub-array from list of array indicies

I have an enum with a computed property that returns an array of indicies:

enum ScaleDegree {
    case tonic
    case supertonic
    case mediant
    case subdominant
    case dominant
    case submedian
    case leading

    var indexes: [Int] {
        switch self {
        case .tonic: return [0,2,4]
        case .supertonic: return [1,3,5]
        case .mediant: return [2,4,6]
        case .subdominant: return [3,5,0]
        case .dominant: return [4,6,1]
        case .submedian: return [5,0,2]
        case .leading: return [6,1,3]
        }
    }
}

I use this to extract a subarry from a larger array:

let cMajor = ["C", "D", "E", "F", "G", "A", "B"]

let cMajorTonic = [cMajor[ScaleDegree.tonic.indexes[0]], cMajor[ScaleDegree.tonic.indexes[1]], cMajor[ScaleDegree.tonic.indexes[2]]]

The cMajorTonic syntax seems cumbersome and I would expect Swift 4 would give me an easier way to extract individual elements into a new array, but my searching hasn't found a clever way to do this.

Are there any suggestions of a better way to write this?

Upvotes: 2

Views: 83

Answers (1)

vacawama
vacawama

Reputation: 154513

This would be a good place to use map:

let cMajor = ["C", "D", "E", "F", "G", "A", "B"]
let cMajorTonic = ScaleDegree.tonic.indexes.map { cMajor[$0] }
print(cMajorTonic)
["C", "E", "G"]

You could add this function to your enum:

func appliedTo(scale: [String]) -> [String] {
    return self.indexes.map { scale[$0] }
}

And then it would become:

let cMajorTonic = ScaleDegree.tonic.appliedTo(scale: cMajor)

Upvotes: 3

Related Questions