4 Replies
      Latest reply: Sep 15, 2016 7:47 AM by macuser1984 RSS
      macuser1984 Level 1 Level 1 (0 points)

        I have a 2d array and am trying to access the index of one of the elements of the outside array (therefore the index for a contained 1d array) as shown in the code below:

        let int2dArray = [[3, 2], [8, 4]]
        for i in int2dArray {
            for j in i {
                let iCurrentIndex = int2dArray.index(of: i)
            }
        }
        

         

        When I try to use index(of: Element), I get the following error message: Cannot invoke 'index' with an argument list of type '(of: Array<Int>)’. I also notice in the code completion suggestions that index(of:) doesn’t show up, but index(where: (Element) -> Bool) does show up. Closures are still a relatively new concept to me (I’m not a total newbie to iOS development but not as experienced yet), so I’m not sure exactly what this method would take as a parameter. Why is this? Does any of this have to do with the element's conformance with Equatable (which is required for this method)?

         

        In Swift 2.x and 1.x (and C++), I could use a C-style for loop and accomplish this because i (in this case) was the actual array index, like so:

        for var i = 0; i < int2dArray.count; i++ {
          for var j = 0; j < int2dArray[i].count; j++ {
               let iCurrentIndex = i
          }
        }
        

         

        Any suggestions?

        Thanks!

        • Re: index(of: Element) on 2d array’s outside array
          QuinceyMorris Level 6 Level 6 (2,465 points)

          It actually looks like a bug in the compiler. You should submit a bug report with the 1st code fragment.

           

          However, if you just want to get hold of the current index, you can do it more easily like this:

           

          let int2dArray = [[3, 2], [8, 4]]
          for (iCurrentIndex, i) in int2dArray.enumerated () {
            for j in i {
                 print (iCurrentIndex, i) // etc
            }
          }
          
          

           

          That "enumerated" method allows you to get the index and the element at the same time.

           

          Edit: Submitted as bug 28294667.

            • Re: index(of: Element) on 2d array’s outside array
              eskimo Apple Staff Apple Staff (6,075 points)

              That "enumerated" method allows you to get the index and the element at the same time.

              Regardless of the following, this is definitely the right way to solve macuser1984’s problems (nice handle btw!).  Everything below is just FYI.


              index(of:) won’t work because it requires Element to be equatable and int2dArray’s elements are of type [Int][Int] values can be compared, they don’t conform to Equatable.

              let a1 = [1, 2, 3]
              let a2 = [1, 2, 3]
              
              func isEquals<X>(_ x: X, _ y: X) -> Bool where X : Equatable {
                  return x == y
              }
              
              print(a1 == a2)
              print(isEquals(a1[0], a2[0]))
              print(isEquals(a1, a2))
              //^^^^^^^^^^^ Argument type '[Int]' does not conform to expected type 'Equatable'
              

              For more background on this, look up “conditional conformance” in the Generics Manifesto.

              Share and Enjoy

              Quinn “The Eskimo!”
              Apple Developer Relations, Developer Technical Support, Core OS/Hardware
              let myEmail = "eskimo" + "1" + "@apple.com"

              • Re: index(of: Element) on 2d array’s outside array
                macuser1984 Level 1 Level 1 (0 points)

                QuinceyMorris - I just tried this solution with my actual code (that's more complicated than the simple example I wrote here), and it now works as I expected it to. It actually cleaned up my code and made it easier to read!

                 

                eskimo - Thanks for the extra information, especially the example!