Reputation: 3
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
Reputation: 7926
(for {
(l, i) <- ll.zipWithIndex
(e, j) <- l.zipWithIndex
if f(e)
} yield (i, j)).headOption
Upvotes: 4
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