WelcomeTo
WelcomeTo

Reputation: 20571

How to optionally return value from map function

map function on collections requires to return some value for each iteration. But I'm trying to find a way to return value not for each iteration, but only for initial values which matches some predicate .

What I want looks something like this:

(1 to 10).map { x =>
   val res: Option[Int] = service.getById(x)
   if (res.isDefined) Pair(x, res.get )// no else part

}

I think something like .collect function could do it, but seems with collect function I need to write many code in guards blocks (case x if {...// too much code here})

Upvotes: 3

Views: 3199

Answers (4)

marios
marios

Reputation: 8996

If you are returning an Option you can flatMap it and get only the values that are present (that is, are not None).

(1 to 10).flatMap { x =>
   val res: Option[Int] = service.getById(x)
   res.map{y => Pair(x, y) }
}

As you suggest, an alternative way to combine map and filter is to use collect and a partially applied function. Here is a simplified example:

(1 to 10).collect{ case x if x > 5 => x*2 }
res0: scala.collection.immutable.IndexedSeq[Int] = Vector(12, 14, 16, 18, 20)

Upvotes: 8

Damien Engels
Damien Engels

Reputation: 39

You can use the collect function (see here) to do exactly what you want. Your example would then look like:

(1 to 10) map (x => (x, service.getById(x))) collect {  
  case (x, Some(res)) => Pair(x, res)
}

Upvotes: 3

elm
elm

Reputation: 20405

Using a for comprehension, like this,

for ( x <- 1 to 10; res <- service.getById(x) ) yield Pair(x, res.get)

This yields pairs where res does not evaluate to None.

Upvotes: 2

Dr. Vick
Dr. Vick

Reputation: 195

Getting the first element:

(1 to 10).flatMap { x =>
   val res: Option[Int] = service.getById(x)
   res.map{y => Pair(x, y) }
}.head

Upvotes: 0

Related Questions