Getting the index in ForEach

I need to get the index as a forEach iterates. Normally, I could just use something like:

var i = 0
for item in array {
    //do stuff
   i += 1
}


But this doesn't work with ForEach. I also tried array.enumerated(), but then it won't let me use .identified(by:) for some reason, so it refuses it as a data source.

Post not yet marked as solved Up vote post of uxjon Down vote post of uxjon
27k views

Replies

hi,


not sure how you tried to use the .enumerated() method -- but be sure you know that array.enumerated() gives pairs of and index and item, so the right code would look something like this:


let array = ["Fred", "Astaire", "Ginger", "Rogers"]

for (index,item) in array.enumerated() {
  print(index,item)
}


this prints out


0 Fred

1 Astaire

2 Ginger

3 Rogers


hope that helps,

DMG

Thanks for the reply.


I can get enumerated() to work fine with normal for loops, the problem comes when I am trying to use it with SwiftUI's ForEach object (normal for loops don't work with SwiftUI yet)

hi,


sorry that i didn't pick up right away on the subtlety here, of it having to do with SwiftUI code -- although it was posted in SwiftUI (duh!) and does mention something about a data source.


on the Swift side, you can certainly do a forEach() instead of an explicit for loop:


array.enumerated().forEach( { print($0.0,$0.1) } )


this will give the same output as what i showed above. can't say where this leads in SwiftUI and a data source, since i haven't gotten to SwiftUI yet (but maybe next month!)


good luck (and apologies for giving a simple answer to a question other than what was asked),

DMG


EDIT: the following code might be more clear for readability than what was above:


array.enumerated().forEach( { (index,item) in print(index,item) } )

I am working around it by getting the index in each loop. I am sure it is not the most efficient way, but it works for the moment:


Foreach(array) { item in
     let index = array.firstIndex(of: item)
}


This, of course, will not work for every array. You could also create a counter on the outside of the foreach and increment it. I haven't tried that one yet, but it could work.

I've been doing the below for now. Compile-time performance drops the more of these you have in a single view but it does work.


ForEach(0..<myArray.count) { index in
    Text(String(describing: myArray[index])).tag(index)
}

You can use:


ForEach(array.indices) { i in
   //do stuff
}


But be careful. This masks the ID of the underlying value, so should only be used for arrays that don't add or remove items.