Tetraedri_
Tetraedri_

Reputation: 3

Functional programming in Scala: find index of an element in a multidimensional list

I have a two-dimensional list ll : List[List[T]] and a function f : T => Boolean. I want to find a tuple (i, j) of integers such that f(l(i)(j)) == true whenever it exists, maybe wrapped inside an Option, and would like to do this in the style of functional programming. My current working solution looks as follows:

ll.zipWithIndex
  .flatMap{case (l, i) => l.map((_, i)).zipWithIndex}
  .find{case ((l, _), j) => f(l(j))}
  .map{case ((_, i), j) => (i, j)}

However, I feel like there should be a nicer way to achieve this - my solution is very cumbersome and doesn't generalize nicely to higher-dimensional arrays. So is there a better way to do this?

Before I go: I'm fully aware this is easily achieved with nested for-loops. So I'm only interested of solutions in the style of functional programming.

Upvotes: 0

Views: 280

Answers (2)

Alex
Alex

Reputation: 7926

(for { 
  (l, i) <- ll.zipWithIndex
  (e, j) <- l.zipWithIndex
  if f(e)
} yield (i, j)).headOption

Upvotes: 4

jwvh
jwvh

Reputation: 51271

You haven't provided any example input to test with, but this appears to work. It returns an IndexedSeq[(Int, Int)] collection that should (I think) contain all the (i,j) pairs where f(ll(i)(j)) returns true.

ll.indices
  .flatMap(i => ll(i).indices
                     .collect{case j if f(ll(i)(j)) => (i,j)})

Which is pretty much the same as this...

for {
  i <- ll.indices
  j <- ll(i).indices
  if f(ll(i)(j))
} yield (i,j)

...and, as mentioned in the comments, is fully FP compatible.

Upvotes: 0

Related Questions