Mandroid
Mandroid

Reputation: 7488

Using scala.Option functionally

I have an Option, say O, which can either be None or may have some value inside. If it has some value, that value may have a flag, say f. My requirement is that if O is None, then I create an object, say of type MyEntity,but if O has a value with flag as true, I return Nil else I create instance of MyEntity with different value. Java code can be almost as:

if(O.isEmpty) {
  MyEntity("x")
} else {
  if(O.f) {
     Nil
   } else {
    MyEntity("y") // with different value
   }
}

I want to do this in functional style using HoFs provided in scala.Option. What would be best possible way of doing it? I could this so far :

if(O.isEmpty){
 MyEntity("x")
} else {
 Option.unless(O.exists(_.f))(MyEntity("y"))
}

Upvotes: 1

Views: 222

Answers (3)

Randomness Slayer
Randomness Slayer

Reputation: 724

I misread your question the first go round, so here is attempt #2

This is a great case for pattern matching:


val maybeMyEntity: Option[MyEntity] = option match {
    case Some(flagValue) if flagValue => None
//  case Some(true) => None (More concise, but does not highlight a handy feature)
    case Some(_) => Some(MyEntity("Y"))
    case None => Some(MyEntity("X"))
}

Pattern matching is very powerful.

Alternatively, mapping is another option:

mapping of an Option will only occur if its value is not empty, and flatMapping will remove the layer of Option added, from Option[Option[MyEntity]] to Option[MyEntity]

val result: Option[MyEntity] = if (option.isEmpty) {
    Some(Entity("X"))
} else {
    option.flatMap { flagValue =>
        if (flagValue) {
            None
        } else {
            Some(MyEntity("Y"))
        }
    }
}

Upvotes: 1

Shan Hadoop Learner
Shan Hadoop Learner

Reputation: 107

    case class AnOption(var flag: Boolean = true)
    
    case class MyEntities(name: String)
    
    val myOptionEntityCheck = (someOption: Option[AnOption]) => {
      someOption match {
        case None => Some(MyEntities("X"))
        case Some(aValue: AnOption) if aValue.flag => None
// OR   case Some(AnOption(true)) => None
        case Some(_) => Some(MyEntities("y"))
      }
    }

Upvotes: 0

Dima
Dima

Reputation: 40500

As mentioned in the comments, Nil type is a List, and your expression should always return the same type (should really not be Any).

One possibility is to define a "sentinel" value for MyEntity, e.g.:

object MyEntity {
   val Nil = MyEntity("")
}

Now you can write:

   val result = O.fold(MyEntity("x")) { 
      case true => MyEntity.Nil
      case false => MyEntity("y")
   }

Upvotes: 0

Related Questions