I have an array of Xs. Each X might have an array of Ys. I want an array of Ys paired with its owning X. I would describe this as turning the array of arrays inside out. I do not want to use for loops.
I made no effort for this code to be concise or performant. The CustomStringConvertible conformance is for human-readable output in the console.
struct Tomato : CustomStringConvertible {
let mass:Double
var description: String {
return "tomato: mass = \(mass)"
}
}
enum Health { case dead, bad, good, perfect }
struct Plant : CustomStringConvertible {
let health:Health
let tomatoes:[Tomato]?
var description: String {
return "plant: health = \(health)"
}
}
struct Pair : CustomStringConvertible {
let tomato:Tomato
let plant:Plant
var description: String {
return "pair:\n\t\(tomato)\n\t\(plant)\n"
}
}
let plants:[Plant] = [
Plant(health: .dead, tomatoes:nil),
Plant(health: .bad, tomatoes: [Tomato(mass:4.6), Tomato(mass:3.32)]),
Plant(health: .good, tomatoes: [Tomato(mass:28.9)])
]
// We want an array of all the tomatoes,
// but each is paired with the plant it comes from.
let pairs:[Pair] = plants.compactMap({ plant in
plant.tomatoes?.map({ tomato in
return Pair(tomato: tomato, plant: plant)
})
}).flatMap({ $0 })
print(pairs)
[pair:
tomato: mass = 4.6
plant: health = bad
, pair:
tomato: mass = 3.32
plant: health = bad
, pair:
tomato: mass = 28.9
plant: health = good
]