This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Suggestions for processing list of Option?

10 replies
Idan Waisman
Joined: 2012-01-10,
User offline. Last seen 42 years 45 weeks ago.
I have on more than one occasion found myself doing something akin to:
val xOptions: Seq[Option[_]]val actualX = xOptions.filter(_.isDefined).map(_.get)
Is there a slicker/more-efficient way of doing this? I presented this as a collection of Option, but more general solutions of essentially doing a conditional map such that the size of the resulting collection is possibly less than the size of the input collection based on some predicate are also welcome.
-Idan
odd
Joined: 2009-04-07,
User offline. Last seen 26 weeks 4 days ago.
Re: Suggestions for processing list of Option?

xOptions.collect { case Some(x) => x }

Greetings
//Odd

On 10 jan 2012, at 20:30, "Idan Waisman" wrote:

> I have on more than one occasion found myself doing something akin to:
>
> val xOptions: Seq[Option[_]]
> val actualX = xOptions.filter(_.isDefined).map(_.get)
>
> Is there a slicker/more-efficient way of doing this? I presented this as a collection of Option, but more general solutions of essentially doing a conditional map such that the size of the resulting collection is possibly less than the size of the input collection based on some predicate are also welcome.
>
> -Idan

ichoran
Joined: 2009-08-14,
User offline. Last seen 2 years 3 weeks ago.
Re: Suggestions for processing list of Option?
Have you tried flatten?  (xOptions.flatten?)

Unless you want something tricky, that should do the job.

If you want something tricky, then collect is probably the closest to what you want.  (There is no explicit filterMap.)

  --Rex

On Tue, Jan 10, 2012 at 2:30 PM, Idan Waisman <iwaisman [at] manaproducts [dot] com> wrote:
I have on more than one occasion found myself doing something akin to:
val xOptions: Seq[Option[_]]val actualX = xOptions.filter(_.isDefined).map(_.get)
Is there a slicker/more-efficient way of doing this? I presented this as a collection of Option, but more general solutions of essentially doing a conditional map such that the size of the resulting collection is possibly less than the size of the input collection based on some predicate are also welcome.
-Idan

Razvan Cojocaru 3
Joined: 2010-07-28,
User offline. Last seen 42 years 45 weeks ago.
RE: Suggestions for processing list of Option?

Can’t we flatMap that sh*t ?

 

scala> val x = Seq (Some(1), None, Some(2))

x: Seq[Option[Int]] = List(Some(1), None, Some(2))

 

scala> x.flatMap (_)

<console>:9: error: missing parameter type for expanded function ((x$1) => x.flatMap(x$1))

              x.flatMap (_)

                         ^

 

scala> x.flatMap ( x => x )

res1: Seq[Int] = List(1, 2)

 

scala>

From: scala-user [at] googlegroups [dot] com [mailto:scala-user [at] googlegroups [dot] com] On Behalf Of Rex Kerr
Sent: January-10-12 2:36 PM
To: scala-user [at] googlegroups [dot] com
Subject: Re: [scala-user] Suggestions for processing list of Option?

 

Have you tried flatten?  (xOptions.flatten?)

Unless you want something tricky, that should do the job.

If you want something tricky, then collect is probably the closest to what you want.  (There is no explicit filterMap.)

  --Rex

On Tue, Jan 10, 2012 at 2:30 PM, Idan Waisman <iwaisman [at] manaproducts [dot] com> wrote:

I have on more than one occasion found myself doing something akin to:

 

val xOptions: Seq[Option[_]]

val actualX = xOptions.filter(_.isDefined).map(_.get)

 

Is there a slicker/more-efficient way of doing this? I presented this as a collection of Option, but more general solutions of essentially doing a conditional map such that the size of the resulting collection is possibly less than the size of the input collection based on some predicate are also welcome.

 

-Idan

 

d_m
Joined: 2010-11-11,
User offline. Last seen 35 weeks 2 days ago.
Re: Suggestions for processing list of Option?

On Tue, Jan 10, 2012 at 04:09:11PM -0500, Razvan Cojocaru wrote:
> Can't we flatMap that sh*t ?

Not necessary, since ns.flatMap(f) is equivalent to ns.map(f).flatten.

If you just need to turn List[Option[X]] into List[X] use flatten.

If you want to use f:X=>Option[Y] to map/filter List[X] to get List[Y],
then use flatMap.

Razvan Cojocaru 3
Joined: 2010-07-28,
User offline. Last seen 42 years 45 weeks ago.
Re: Suggestions for processing list of Option?

Flatten requires you to peek inside the Option, so it's both more complicated and longer?

Thanks,
Razvan

On 2012-01-10, at 4:23 PM, Erik Osheim wrote:

> On Tue, Jan 10, 2012 at 04:09:11PM -0500, Razvan Cojocaru wrote:
>> Can't we flatMap that sh*t ?
>
> Not necessary, since ns.flatMap(f) is equivalent to ns.map(f).flatten.
>
> If you just need to turn List[Option[X]] into List[X] use flatten.
>
> If you want to use f:X=>Option[Y] to map/filter List[X] to get List[Y],
> then use flatMap.
>

Razvan Cojocaru 3
Joined: 2010-07-28,
User offline. Last seen 42 years 45 weeks ago.
Re: Suggestions for processing list of Option?

Thats what I get for writing emails before coffee. I thought you were talking about collect. My bad.

Thanks,
Razvan

On 2012-01-11, at 7:21 AM, Razvan Cojocaru wrote:

> Flatten requires you to peek inside the Option, so it's both more complicated and longer?
>
> Thanks,
> Razvan
>
> On 2012-01-10, at 4:23 PM, Erik Osheim wrote:
>
>> On Tue, Jan 10, 2012 at 04:09:11PM -0500, Razvan Cojocaru wrote:
>>> Can't we flatMap that sh*t ?
>>
>> Not necessary, since ns.flatMap(f) is equivalent to ns.map(f).flatten.
>>
>> If you just need to turn List[Option[X]] into List[X] use flatten.
>>
>> If you want to use f:X=>Option[Y] to map/filter List[X] to get List[Y],
>> then use flatMap.
>>

Tony Morris 2
Joined: 2009-03-20,
User offline. Last seen 42 years 45 weeks ago.
Re: Suggestions for processing list of Option?

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 01/11/2012 05:30 AM, Idan Waisman wrote:
> I have on more than one occasion found myself doing something akin to:
>
> val xOptions: Seq[Option[_]]
> val actualX = xOptions.filter(_.isDefined).map(_.get)
>
> Is there a slicker/more-efficient way of doing this? I presented this as a
> collection of Option, but more general solutions of essentially doing a
> conditional map such that the size of the resulting collection is possibly
> less than the size of the input collection based on some predicate are also
> welcome.
>
> -Idan
>

Yes, there are more general solutions. Take a seat.

If we take a functor to be defined like so:

scala> trait Functor[F[_]] { def fmap[A, B](f: A => B): F[A] => F[B] }
defined trait Functor

and an applicative functor to be defined:

scala> trait Applicative[F[_]] extends Functor[F] { override final def
fmap[A, B](f: A => B) = ap(point(f)); def point[A](a: => A): F[A]; def
ap[A, B](f: F[A => B]): F[A] => F[B] }
defined trait Applicative

I mention these two interfaces because applicative functors compose
while monads do not. http://blog.tmorris.net/monads-do-not-compose This
fact will help us soon.

Now if we define an interface that adds a monoid to applicative functors

Brian Maso
Joined: 2011-07-21,
User offline. Last seen 42 years 45 weeks ago.
Re: Suggestions for processing list of Option?
My brain has missed being kicked around by Tony. Thanks for this post!

Also, we really need some Scala sugar for partially-applied types (or whatever the name for this should be): ({type λ[α]=Compose[F, G, α]})#λ.

Brian Maso

On Wed, Jan 11, 2012 at 6:10 AM, Tony Morris <tonymorris [at] gmail [dot] com> wrote:
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 01/11/2012 05:30 AM, Idan Waisman wrote:
> I have on more than one occasion found myself doing something akin to:
>
> val xOptions: Seq[Option[_]]
> val actualX = xOptions.filter(_.isDefined).map(_.get)
>
> Is there a slicker/more-efficient way of doing this? I presented this as a
> collection of Option, but more general solutions of essentially doing a
> conditional map such that the size of the resulting collection is possibly
> less than the size of the input collection based on some predicate are also
> welcome.
>
> -Idan
>

Yes, there are more general solutions. Take a seat.

If we take a functor to be defined like so:

scala> trait Functor[F[_]] { def fmap[A, B](f: A => B): F[A] => F[B] }
defined trait Functor

and an applicative functor to be defined:

scala> trait Applicative[F[_]] extends Functor[F] { override final def
fmap[A, B](f: A => B) = ap(point(f)); def point[A](a: => A): F[A]; def
ap[A, B](f: F[A => B]): F[A] => F[B] }
defined trait Applicative

I mention these two interfaces because applicative functors compose
while monads do not. http://blog.tmorris.net/monads-do-not-compose This
fact will help us soon.

Now if we define an interface that adds a monoid to applicative functors
hohonuuli
Joined: 2009-08-30,
User offline. Last seen 3 years 9 weeks ago.
Re: Suggestions for processing list of Option?

> > I have on more than one occasion found myself doing something akin to:
> >
> > val xOptions: Seq[Option[_]]
> > val actualX = xOptions.filter(_.isDefined).map(_.get)
> >
> Yes, there are more general solutions. Take a seat.
>
Nice post! Thanks for taking the time to put that together.

d_m
Joined: 2010-11-11,
User offline. Last seen 35 weeks 2 days ago.
Re: Suggestions for processing list of Option?

On Wed, Jan 11, 2012 at 02:29:48PM -0800, Brian Maso wrote:
> Also, we really need some Scala sugar for partially-applied types (or
> whatever the name for this should be): ({type λ[α]=Compose[F, G, α]})#λ.

Agreed.

I feel like it should be possible to write some kind of compiler plugin
to translate:

Compose[F, G, __] into ({type L[A]=Compose[F, G, A]})
Foo[__, Int, __] into ({type L[A,B]=Foo[A,Int,B]})
...etc...

(substitute your preferred "wildcard" for __, e.g. ? or *)

But I haven't had the time to look into it (bigger fish to fry).

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland