1

I am having a bit of hard time thinking in Scala and I keep going back to the imperative model style of thinking. What Scala pattern can I use to implement in the Scala way the following rough pseudocode:

for (item in list)
{
  val result = some_func(item) // result is a pair (Boolean, some data)
  if (result._1)
    return result
}
return (false, null)

Thank you

boggy
  • 3,674
  • 3
  • 33
  • 56

2 Answers2

3

You could use map to apply the function, then find to find a mapped value for which _1 == true, which gives an Option, and then use getOrElse to return a default value.

def perform[A, B](list: List[A])(fun: A => (Boolean, B)): (Boolean, B) =
  list.map(fun).find(_._1).getOrElse((false, null.asInstanceOf[B]))

The disadvantage is that map will apply fun to all elements, whereas you would prefer to abort on the first element for which _1 == true:

val xs = List(1, 2, 3, 4)

perform(xs) { x =>
  println(s"Testing $x")
  (x % 2 == 0, x / 2)
}
Testing 1
Testing 2
Testing 3
Testing 4
res0: (Boolean, Int) = (true,1)

One possibility is to use an iterator:

def perform[A, B](list: List[A])(fun: A => (Boolean, B)): (Boolean, B) =
  list.iterator.map(fun).find(_._1).getOrElse((false, null.asInstanceOf[B]))
Testing 1
Testing 2
res1: (Boolean, Int) = (true,1)

Also, consider returning an Option[B] instead of (Boolean, B), that way you avoid the ugliness of null and it's safer to handle on the return side:

def perform[A, B](list: List[A])(fun: A => (Boolean, B)): Option[B] =
  list.iterator.map(fun).collectFirst { case (true, res) => res }

Regarding iterator vs view:

I find it always easier to keep track of iterators as long as they offer the methods required. I also think the view mechanism will be reworked in future collections.

0__
  • 66,707
  • 21
  • 171
  • 266
0

Based on this post: Finding elements in a scala list and also know which predicate has been satisfied I came up with this:

list.view.map(el => (el, some_func(el))).find(t => t._2._1)
boggy
  • 3,674
  • 3
  • 33
  • 56