2

I want to know about syntax of using enumerated with ForEach. I am using a customID.

Here is my code:

ForEach(arrayNew.enumerated(), id:\.customID) { (index, item) in

}

Update:

ForEach(Array(arrayNew.enumerated()), id:\.element.customID) { (index, item) in
    Text(String(index) + item)  
}
pawello2222
  • 46,897
  • 22
  • 145
  • 209
  • 2
    Does this answer your question https://stackoverflow.com/a/62384275/12299030? Or this https://stackoverflow.com/a/59863409/12299030? – Asperi Dec 30 '20 at 19:33
  • thanks a lot, I do not understand why I should put my arrayNew in another Array? why? also please see my update for any improvement –  Dec 30 '20 at 19:44

1 Answers1

4

Let's assume we have an Array of objects of type Item:

struct Item {
    let customID: Int
    let value: String
}

let arrayNew = [
    Item(customID: 1, value: "1"),
    Item(customID: 23, value: "12"),
    Item(customID: 2, value: "32")
]

Now, if we want to access both offset and item from the array, we need to use enumerated():

arrayNew.enumerated()

However, it returns an EnumeratedSequence (and not an Array):

@inlinable public func enumerated() -> EnumeratedSequence<Array<Element>>

If we take a look at the signature of ForEach, we can see that it expects RandomAccessCollection:

public struct ForEach<Data, ID, Content> where Data : RandomAccessCollection, ID : Hashable

The problem here is that EnumeratedSequence doesn't conform to RandomAccessCollection.

But Array does - we just need to convert the result of enumerated() back to an Array:

Array(arrayNew.enumerated())

Now, we can use it directly in the ForEach:

ForEach(Array(arrayNew.enumerated()), id: \.element.customID) { offset, item in
    Text("\(offset) \(item.customID) \(item.value)")
}
pawello2222
  • 46,897
  • 22
  • 145
  • 209
  • That is good to understand why I have to use Array() but why we do not need it here: ** for (index, item) in <#T##items: Any...##Any#>.enumerated() { <#T##items: Any...##Any#> } ** –  Dec 30 '20 at 21:54
  • @mimi This is because `for-in` loop requires conformance to `Sequence` - which applies to both `Array` and `EnumeratedSequence`. The *standard* `for-in` loop is completely different from SwiftUI `ForEach`. – pawello2222 Dec 30 '20 at 21:57
  • so helpful, thanks again! My last but least question, when we use enumerated() in our codes, does put side effect in our app? is it make it expensive to run codes with enumerated method? I mean if I just use my codes without enumerated is it faster in run time? –  Dec 30 '20 at 22:02
  • 1
    @mimi As far as I know, you shouldn't see any difference. – pawello2222 Dec 30 '20 at 22:24