0

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.

1
  • 1
    for comprehensions are just syntactic sugar for map() and flatMap() calls. What's non-FP about that? Commented Jun 17, 2021 at 6:39

2 Answers 2

4
(for { 
  (l, i) <- ll.zipWithIndex
  (e, j) <- l.zipWithIndex
  if f(e)
} yield (i, j)).headOption
Sign up to request clarification or add additional context in comments.

Comments

0

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.

2 Comments

Just one note, accessing by index a List is pretty slow it would be better to use zipWithIndex and maybe using also Iterators to do everything in a single iteration.
Ugh ... this is worse than even quadratic :/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.