Это не только неэффективно, но и опасно. Что, если мы немного изменим?
val row = table indexWhere (_.indexOf(101) != -1)
val col = table(row) indexOf 42 //Uh-oh, IndexOutOfBounds!
Это действительно кажется, подходит к для-выражения:
val z =
for {
i <- 0 until table.length
j <- 0 until table(i).length
if (table(i)(j) == 42)
} yield (i, j)
z.headOption.getOrElse(-1, -1)
Это может быть слишком важно, но все это трансформируется в flatMap
и filter
под капотом. Вы могли бы написать это с этим, но это гораздо более читаемо.
Edit: Если вы хотите, отказоустойчивости быстрого поведения, рекурсивное решение будет соответствовать всем требованиям:
def findElement(table: Vector[Vector[Int]], elem: Int): (Int, Int) = {
@tailrec
def feRec(row: Int, col: Int): (Int, Int) = {
if (row == table.length) (-1, -1)
else if (col == table(row).length) feRec(row + 1, 0)
else if (table(row)(col) == elem) (row, col)
else feRec(row, col + 1)
}
feRec(0, 0)
}
Ах, да, забыл о недостающих элементах. Разве это не будет проходить через каждый элемент таблицы, хотя, независимо от того, как скоро будет найдено первое совпадение? – servechilledorhot
@ChrisCano Да, он пройдет через каждый элемент таблицы, поэтому не останавливаться при первом вхождении. – Yuushi
Вы можете изменить первое условие на «i <- (0 до table.length) .toStream», чтобы сделать его ленивым и остановить в первом матче. –