2

I have a 2d array with custom types.

I'd like to do something like:

HStack {
    ForEach(2dArray) { x in
        VStack {
            ForEach(self.2dArray[x.index]) { y in

The main issue I have is that I can't figure out how to get x.index.

4 Answers 4

2

So I was going to say you should do this to iterate a 2D array:

var data = [[1,2,3],[4,5,6],[7,8,9]]

ForEach(data.identified(by: \.self)) { array in
    ForEach(array.identified(by: \.self)) { element in
        Text("\(element)")
    }
}

but XCode 11 beta is still very buggy with SwiftUI and type inference, so you get a compiler error for doing that, even though it should work. So for now, you'll have to separate everything into functions that the XCode compiler can handle, but with the complex types that SwiftUI uses, it gets ugly very fast. Here is an example:

var data = [[1,2,3],[4,5,6],[7,8,9]]

var body: some View {
    doubleForEach(data: data)
}
func doubleForEach(data: [[Int]]) -> ForEach<IdentifierValuePairs<[[Int]], [Int]>,ForEach<IdentifierValuePairs<[Int], Int>, Text>> {
    return ForEach(data.identified(by: \.self)) { row in
        self.foreach(dataArr: row)
    }
}
func foreach(dataArr: [Int]) -> ForEach<IdentifierValuePairs<[Int], Int>, Text> {
    return ForEach(dataArr.identified(by: \.self)) { data in
        Text("\(data)")
    }
}

Which looks like this:

Sign up to request clarification or add additional context in comments.

2 Comments

Ohhh...k. I think I'm following; I'll try to implement this. Thank you!
No problem! And as mimo said, you might want to see if the code that didn't work for me works for you, since Xcode 11's buggy compiler can give false errors on a case by case basis. If it doesn't work then you should go the ugly functions route, at least until you can clean it up later when Apple starts releasing Xcode 11 updates.
2
var data = [[1,2,3],[4,5,6],[7,8,9]]

struct ContentView : View {
  var body: some View {
    VStack {
      ForEach(data, id: \.self) { array in
        HStack{
          ForEach(array, id: \.self) { element in
            Text("\(element)")
          }
        }
      }
    }
  }
}

Comments

1

actually the example RPatel99 postet in the earlier response works fine for me:

var data = [[1,2,3],[4,5,6],[7,8,9]]

struct ForTesting : View {
    var body: some View {
        VStack {
            ForEach(data.identified(by: \.self)) { array in
                ForEach(array.identified(by: \.self)) { element in
                    Text("\(element)")
                }
            }
        }
    }
}

But was this your problem?

3 Comments

Thanks for the info! But this post would probably work better as a comment on my answer than as a separate answer.
It works. I just needed to (1) change self.2dArray[x.index] to just the array I get from the first ForEach. (2) make my types hashable to be able to use .self. Thanks for the help!
thanks. in fact I wanted to do this as a comment but was not yet able to do comments (reputation < 50)
0
struct ContentView : View {
  var body: some View {
    VStack {
      ForEach(data.identified(by: \.self)) { array in
        HStack{
          ForEach(array.identified(by: \.self)) { element in
            Text("\(element)")
          }
        }
      }
    }
  }
}

enter image description here

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.