Eccles
Eccles

Reputation: 412

How to get the index of an item in a 2D array?

If I have an array:

let array = [
        ["Hamburger", "Nachos", "Lasagne"],
        ["Tomatoes", "Apples", "Oranges"],
        ["Soda", "Juice", "Water"]
    ]    

What is the index of for example "Apples"? And is there a way to get it programmaticly?

Upvotes: 0

Views: 334

Answers (4)

Leo Dabus
Leo Dabus

Reputation: 236420

You can use firstIndex(where:) and find the subindex of it using firstIndex(of:):

let array = [
    ["Hamburger", "Nachos", "Lasagne"],
    ["Tomatoes", "Apples", "Oranges"],
    ["Soda", "Juice", "Water"]
]

let query = "Apples"
if let index = array.firstIndex(where: {$0.contains(query)}),
    let subIndex = array[index].firstIndex(of: query) {
    print(array[index][subIndex])  // Apples

}

As an Extension:

extension Collection where Element: Collection, Element.Element: Equatable {
    func firstIndexAndSubIndex(of element: Element.Element) -> (index: Index, subIndex: Element.Index)? {
        if let index = firstIndex(where: {$0.contains(element)}),
            let subIndex = self[index].firstIndex(of: element) {
            return (index,subIndex)
        }
        return nil
    }
}

usage:

let array = [
    ["Hamburger", "Nachos", "Lasagne"],
    ["Tomatoes", "Apples", "Oranges"],
    ["Soda", "Juice", "Water"]
]
let query = "Soda"
if let indexes = array.firstIndexAndSubIndex(of: query) {
    print(indexes)   // "(index: 2, subIndex: 0)\n"
}

This would work also to find the index of a character from an array of strings:

let array = ["Hamburger", "Nachos", "Lasagne"]
let query: Character = "h"
if let indices = array.indexAndSubIndex(of: query) {
    print(indices)   // "(index: 1, subIndex: Swift.String.Index(_rawBits: 196865))\n"
    array[indices.index][indices.subIndex]  // "h"
}

Upvotes: 6

KimNguyen
KimNguyen

Reputation: 1791

Its not elegant but simple to read

func getIndices(arr: [[String]], word: String) -> (Int, Int)? {
  for i in 0..<arr.count {
    let subArr = arr[i]
    if let index = subArr.index(of: word) {
        return (i, index)
    }
  }
  return nil
}
let result = getIndices(arr: array, word: "Apples"))

Upvotes: 0

Yannick
Yannick

Reputation: 3278

Another option as an extension. The function tupleIndex(of:) returns a tuple of (Int, Int)?.

let array = [
    ["Hamburger", "Nachos", "Lasagne"],
    ["Tomatoes", "Apples", "Oranges"],
    ["Soda", "Juice", "Water"]
]

extension Collection where
    Element: Collection,
    Element.Element: Equatable,
    Element.Index == Int {

    func tupleIndex(of elementToFind: Element.Element) -> (Int, Int)? {
        for (firstIndex, element) in self.enumerated() {
            if let secondIndex = element.index(of: elementToFind) {
                return (firstIndex, secondIndex)
            }
        }
        return nil
    }
}

You can use it like this:

print(array.tupleIndex(of: "Apples")) //prints Optional((1, 1))

Upvotes: 0

Mike Tung
Mike Tung

Reputation: 4821

let array = [
        ["Hamburger", "Nachos", "Lasagne"],
        ["Tomatoes", "Apples", "Oranges"],
        ["Soda", "Juice", "Water"]
]

for arr in array {

  let answer = arr.indexOf("Apples")
  if answer {
    break
  }
print(answer)
}

Upvotes: -3

Related Questions