2

I would like to create a method that takes as arguments an array of options and a default value and return the first non empty option otherwise the default value :

def customGetOrElse[T](options : Array[Option[T]], defaultValue : T) : T = {
  // Example if options contain 2 elements
  options(0).getOrElse(options(1).getOrElse(defaultValue))
  // If options contain 3 elements
  options(0).getOrElse(options(1).getOrElse(options(2).getOrElse(defaultValue)))
}

But I am struggling to make this method working for any size of the array. Any ideas ?

Thanks!

Zied Koubaa
  • 213
  • 1
  • 18

3 Answers3

4
def customGetOrElse[T](options : Array[Option[T]], defaultValue : T) : T = {
  options.find(_.isDefined).flatten.getOrElse(defaultValue)
}
Joe K
  • 18,204
  • 2
  • 36
  • 58
4

The one with collectFirst

def customGetOrElse[T](options: Array[Option[T]], defaultValue: T): T =
 options.collectFirst { case Some(value) => value }.getOrElse(defaultValue)

Scala REPL

Welcome to Scala 2.12.6 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_162).
Type in expressions for evaluation. Or try :help.

scala> :paste
// Entering paste mode (ctrl-D to finish)


 def customGetOrElse[T](options: Array[Option[T]], defaultValue: T): T =
  options.collectFirst { case Some(value) => value }.getOrElse(defaultValue)

// Exiting paste mode, now interpreting.

customGetOrElse: [T](options: Array[Option[T]], defaultValue: T)T

scala> customGetOrElse[Int](Array(None, Some(1)), 2)
res0: Int = 1

scala> customGetOrElse[Int](Array(None, None), 2)
res1: Int = 2
Nagarjuna Pamu
  • 14,737
  • 3
  • 22
  • 40
1

Use flatten over the options to reduce options to those that have a value. Then use headOption to return an Option containing the first value present or None. Lastly, get the value T from the Option or return the defaultValue.

def customGetOrElse[T](options : Array[Option[T]], defaultValue : T) : T = {
  options.flatten.headOption.getOrElse(defaultValue)
}

Examples:

scala> customGetOrElse[Int](Array(None, None), 666)
res29: Int = 666

scala> customGetOrElse[Int](Array(None, Some(42)), 666)
res30: Int = 42
Brian
  • 20,195
  • 6
  • 34
  • 55
  • 1
    Why flatten the whole Array ? The non-empty option might be the first or second one, that flatten operation itself will be O(n). – sarveshseri Jun 06 '18 at 18:11
  • Good call. Was just thinking about getting the proper shape of things and not performance. – Brian Jun 06 '18 at 18:23