I have an interesting problem which is proving difficult for someone new to Scala.
I need to combine 2 lists:
listA : List[List[Int]]
listB : List[Int]
In the following way:
val listA = List(List(1,1), List(2,2))
val listB = List(3,4)
val listC = ???
// listC: List[List[Int]] = List(List(1,1,3),List(1,1,4),List(2,2,3),List(2,2,4)
In Java, I would use a couple of nested loops:
for(List<Integer> list : listA) {
for(Integer i: listB) {
subList = new ArrayList<Integer>(list);
subList.add(i);
listC.add(subList);
}
}
I'm guessing this is a one liner in Scala, but so far it's eluding me.
You want to perform a flattened Cartesian product. For-comprehensions are the easiest way to do this and may look similar to your Java solution:
val listC = for (list <- listA; i <- listB) yield list :+ i
scand1sk's answer is almost certainly the approach you should be using here, but as a side note, there's another way of thinking about this problem. What you're doing is in effect lifting the append operation into the applicative functor for lists. This means that using Scalaz you can write the following:
import scalaz._, Scalaz._
val listC = (listA |#| listB)(_ :+ _)
We can think of (_ :+ _) as a function that takes a list of things, and a single thing of the same type, and returns a new list:
(_ :+ _): ((List[Thing], Thing) => List[Thing])
Scalaz provides an applicative functor instance for lists, so we can in effect create a new function that adds an extra list layer to each of the types above. The weird (x |#| y)(_ :+ _) syntax says: create just such a function and apply it to x and y. And the result is what you're looking for.
And as in the for-comprehension case, if you don't care about order, you can make the operation more efficient by using :: and flipping the order of the arguments.
For more information, see my similar answer here about the cartesian product in Haskell, this introduction to applicative functors in Scala, or this blog post about making the syntax for this kind of thing a little less ugly in Scala. And of course feel free to ignore all of the above if you don't care.
Related
I use sequenceU to turn inside type out while working with disjunctions in scalaz.
for e.g.
val res = List[\/[Errs,MyType]]
doing
res.sequenceU will give \/[Errs,List[MyType]]
Now if I have a val res2 = List[(\/[Errs,MyType], DefModel)] - List containing tuples of disjunctions; what's the right way to convert
res2 to \/[Errs,List[ (Mype,DefModel)]
As noted in the comments, the most straightforward way to write this is probably just with a traverse and map:
def sequence(xs: List[(\/[Errs, MyType], DefModel)]): \/[Errs, List[(MyType, DefModel)]] =
xs.traverseU { case (m, d) => m.map((_, d)) }
It's worth noting, though, that tuples are themselves traversable, so the following is equivalent:
def sequence(xs: List[(\/[Errs, MyType], DefModel)]): \/[Errs, List[(MyType, DefModel)]] =
xs.traverseU(_.swap.sequenceU.map(_.swap))
Note that this would be even simpler if the disjunction were on the right side of the tuple. If you're willing to make that change, you can also more conveniently take advantage of the fact that Traverse instances compose:
def sequence(xs: List[(DefModel, \/[Errs, MyType])]): \/[Errs, List[(DefModel, MyType)]] =
Traverse[List].compose[(DefModel, ?)].sequenceU(xs)
I'm using kind-projector here but you could also write out the type lambda.
I'm completely new to scala and don't understand why this list isn't coming out right. When I run the program I just get List() as output when I should be getting a list of all the elements of the parameter squared. This should be very simple but the :+ operation is what I've found online and it isn't working.
def Squareall (l: List[Int]): List[Int] ={
var r : List[Int]=List()
for (i<-0 to l.length-1){
r:+ l(i)*l(i)
}
return r
}
The imperative coding style you have in your example is usually avoided in Scala. The for in Scala is an expression, meaning it results in a value, and thus you can transform your input list directly. To use a for to transform your input List you could do something like this:
def squareAll (l: List[Int]): List[Int] = {
for (i <- l) yield i * i
}
If you don't supply the yield statement a for results in the Unit type, which is like void in Java. This flavor of for loop is generally for producing side effects, like printing to the screen or writing to a file. If you really just want to transform the data, then there is no need to create and manipulate the resulting List. (Also method names in Scala are generally "camel cased".)
Most people would probably use the List.map method instead, though:
def squareAll (l: List[Int]) = l.map((x: Int) => x * x)
or even...
def squareAll (l: List[Int]) = l.map(Math.pow(_, 2.0))
You have to assign the newly created list to r like this:
r = r:+ l(i)*l(i)
This is because by default List in Scala is immutable and :+ returns a new list, doesn't update the old one.
Of course there's also a mutable variation of a list scala.collection.mutable.MutableList. You can use the .++= method on it to grow the collection.
val mutableList = scala.collection.mutable.MutableList(1, 2)
mutableList.++=(List(3, 4))
I have a model, which has some Option fields, which contain another Option fields. For example:
case class First(second: Option[Second], name: Option[String])
case class Second(third: Option[Third], title: Option[String])
case class Third(numberOfSmth: Option[Int])
I'm receiving this data from external JSON's and sometimes this data may contain null's, that was the reason of such model design.
So the question is: what is the best way to get a deepest field?
First.get.second.get.third.get.numberOfSmth.get
Above method looks really ugly and it may cause exception if one of the objects will be None. I was looking in to Scalaz lib, but didn't figure out a better way to do that.
Any ideas?
The solution is to use Option.map and Option.flatMap:
First.flatMap(_.second.flatMap(_.third.map(_.numberOfSmth)))
Or the equivalent (see the update at the end of this answer):
First flatMap(_.second) flatMap(_.third) map(_.numberOfSmth)
This returns an Option[Int] (provided that numberOfSmth returns an Int). If any of the options in the call chain is None, the result will be None, otherwise it will be Some(count) where count is the value returned by numberOfSmth.
Of course this can get ugly very fast. For this reason scala supports for comprehensions as a syntactic sugar. The above can be rewritten as:
for {
first <- First
second <- first .second
third <- second.third
} third.numberOfSmth
Which is arguably nicer (especially if you are not yet used to seeing map/flatMap everywhere, as will certainly be the case after a while using scala), and generates the exact same code under the hood.
For more background, you may check this other question: What is Scala's yield?
UPDATE:
Thanks to Ben James for pointing out that flatMap is associative. In other words x flatMap(y flatMap z))) is the same as x flatMap y flatMap z. While the latter is usually not shorter, it has the advantage of avoiding any nesting, which is easier to follow.
Here is some illustration in the REPL (the 4 styles are equivalent, with the first two using flatMap nesting, the other two using flat chains of flatMap):
scala> val l = Some(1,Some(2,Some(3,"aze")))
l: Some[(Int, Some[(Int, Some[(Int, String)])])] = Some((1,Some((2,Some((3,aze))))))
scala> l.flatMap(_._2.flatMap(_._2.map(_._2)))
res22: Option[String] = Some(aze)
scala> l flatMap(_._2 flatMap(_._2 map(_._2)))
res23: Option[String] = Some(aze)
scala> l flatMap(_._2) flatMap(_._2) map(_._2)
res24: Option[String] = Some(aze)
scala> l.flatMap(_._2).flatMap(_._2).map(_._2)
res25: Option[String] = Some(aze)
There is no need for scalaz:
for {
first <- yourFirst
second <- f.second
third <- second.third
number <- third.numberOfSmth
} yield number
Alternatively you can use nested flatMaps
This can be done by chaining calls to flatMap:
def getN(first: Option[First]): Option[Int] =
first flatMap (_.second) flatMap (_.third) flatMap (_.numberOfSmth)
You can also do this with a for-comprehension, but it's more verbose as it forces you to name each intermediate value:
def getN(first: Option[First]): Option[Int] =
for {
f <- first
s <- f.second
t <- s.third
n <- t.numberOfSmth
} yield n
I think it is an overkill for your problem but just as a general reference:
This nested access problem is addressed by a concept called Lenses. They provide a nice mechanism to access nested data types by simple composition. As introduction you might want to check for instance this SO answer or this tutorial. The question whether it makes sense to use Lenses in your case is whether you also have to perform a lot of updates in you nested option structure (note: update not in the mutable sense, but returning a new modified but immutable instance). Without Lenses this leads to lengthy nested case class copy code. If you do not have to update at all, I would stick to om-nom-nom's suggestion.
If I want to generalize the following method to all collection types that support all the necessary operations (foldLeft, flatMap, map, and :+) then how do I do it? Currently it only works with lists.
Code:
def join[A](lists: List[List[A]]): List[List[A]] = {
lists.foldLeft(List(List[A]())) { case (acc, cur) =>
for {
a <- acc
c <- cur
} yield a :+ c
}
}
If you want this only for collections that support :+, the easiest way is just to define it in terms of Seq instead of List.
You can make it a lot more generic, all the way down to Traversable, by using builders. I'd be happy to explain that when I have a bit more time on my hands, but it tends to get complicated at that level.
Scalaz applicative functors is probably the way to go, but I'll let someone with more Scalaz experience than me handle that particular answer.
I have an Iterator[Option[T]] and I want to get an Iterator[T] for those Options where T isDefined. There must be a better way than this:
it filter { _ isDefined} map { _ get }
I would have thought that it was possible in one construct... Anybody any ideas?
In the case where it is an Iterable
val it:Iterable[Option[T]] = ...
it.flatMap( x => x ) //returns an Iterable[T]
In the case where it is an Iterator
val it:Iterator[Option[T]] = ...
it.flatMap( x => x elements ) //returns an Iterator[T]
it.flatMap( _ elements) //equivalent
In newer versions this is now possible:
val it: Iterator[Option[T]] = ...
val flatIt = it.flatten
This works for me (Scala 2.8):
it.collect {case Some(s) => s}
To me, this is a classic use case for the monadic UI.
for {
opt <- iterable
t <- opt
} yield t
It's just sugar for the flatMap solution described above, and it produces identical bytecode. However, syntax matters, and I think one of the best times to use Scala's monadic for syntax is when you're working with Option, especially in conjunction with collections.
I think this formulation is considerably more readable, especially for those not very familiar with functional programming. I often try both the monadic and functional expressions of a loop and see which seems more straightforward. I think flatMap is hard name for most people to grok (and actually, calling it >>= makes more intuitive sense to me).