how to map elements of an array with their occurrence number

Hello,

I have an array of objects that has a type attribute of enum Animals. the type can be like this [Cat, Dog, Cat, Cat, Dog, Mouse, Dog]

I would like to display to my view an output of an image for every object along with the type and its number.

My problem is I cannot get the number from the array. The output should look like :

[Cat1, Dog1, Cat2, Cat3, Dog2, Mouse1, Dog3]

Any ideas how can i achieve this?

Where do the numbers come from? Are they associated values of the enum cases? Are they simply generated sequentially from the order in the array?

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)
}
2 Likes

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?

public extension Sequence where Element: Hashable {
  func withExclusiveIterations<Iterable: Sequence>(of iterable: Iterable)
  -> [(Element, Iterable.Element)] {
    var iterators: [Element: Iterable.Iterator] = [:]
    return map {
      ($0, iterators[$0, default: iterable.makeIterator()].next()!)
    }
  }
}
[Animal.cat, .dog, .cat, .cat, .dog, .mouse, .dog]
  .withExclusiveIterations(of: 1...)