You could build up a new array, keeping track of the counts in a dictionary as you go:
var runningTotals: [Animal: Int] = [:]
var animalCounts: [Int] = []
animalCounts.reserveCapacity(animals.count)
for animal in animals {
let n = runningTotals[animal, default: 0] + 1
runningTotals[animal] = n
animalCounts.append(n)
}
The dictionary solution is good. But there are iterators built into the standard library which implement the behavior already. I think this might be the simplest one?