Scala concatenate lists with foldRight - scala

I making function of list to list adding.
I can't understand why it's doesn't working
def lconcat(l: List[List[Int]]): List[Int] = {
return l.foldRight(1)((x:List[Int], y:List[Int]) => x ++ y)
}
and I call function like
println(lconcat(List(List(1, 2, 3), List(4, 5, 6))))
I want result like List[Int] = List(1, 2, 3, 4, 5, 6)

Since you want to return List of Integers, the parameter of foldRight should be an empty list that the input lists will be concatenated to it.
Your code should be:
def lconcat(l: List[List[Int]]): List[Int] = {
l.foldRight(List.empty[Int])((x:List[Int], y: List[Int]) => {
x ++ y
})
}

Related

Merge two collections by interleaving values

How can I merge two lists / Seqs so it takes 1 element from list 1, then 1 element from list 2, and so on, instead of just appending list 2 at the end of list 1?
E.g
[1,2] + [3,4] = [1,3,2,4]
and not [1,2,3,4]
Any ideas? Most concat methods I've looked at seem to do to the latter and not the former.
Another way:
List(List(1,2), List(3,4)).transpose.flatten
So maybe your collections aren't always the same size. Using zip in that situation would create data loss.
def interleave[A](a :Seq[A], b :Seq[A]) :Seq[A] =
if (a.isEmpty) b else if (b.isEmpty) a
else a.head +: b.head +: interleave(a.tail, b.tail)
interleave(List(1, 2, 17, 27)
,Vector(3, 4)) //res0: Seq[Int] = List(1, 3, 2, 4, 17, 27)
You can do:
val l1 = List(1, 2)
val l2 = List(3, 4)
l1.zip(l2).flatMap { case (a, b) => List(a, b) }
Try
List(1,2)
.zip(List(3,4))
.flatMap(v => List(v._1, v._2))
which outputs
res0: List[Int] = List(1, 3, 2, 4)
Also consider the following implicit class
implicit class ListIntercalate[T](lhs: List[T]) {
def intercalate(rhs: List[T]): List[T] = lhs match {
case head :: tail => head :: (rhs.intercalate(tail))
case _ => rhs
}
}
List(1,2) intercalate List(3,4)
List(1,2,5,6,6,7,8,0) intercalate List(3,4)
which outputs
res2: List[Int] = List(1, 3, 2, 4)
res3: List[Int] = List(1, 3, 2, 4, 5, 6, 6, 7, 8, 0)

Splitting List into List of List

How can I convert:
List(1,1,1,1,4,2,2,2,2)
into:
List(List(1,1,1,1), List(2,2,2,2))
Thought this would be the easiest way to show what I'm looking for. I am having a hard time trying to find the most functional way to do this with a large list that needs to be separated at a specific element. This element does not show up in the new list of lists. Any help would be appreciated!
If you want to support multiple instances of that separator, you can use foldRight with some list "gymnastics":
// more complex example: separator (4) appears multiple times
val l = List(1,1,1,1,4,2,2,2,2,4,5,6,4)
val separator = 4
val result = l.foldRight(List[List[Int]]()) {
case (`separator`, res) => List(Nil) ++ res
case (v, head :: tail) => List(v :: head) ++ tail
case (v, Nil) => List(List(v))
}
// result: List(List(1, 1, 1, 1), List(2, 2, 2, 2), List(5, 6))
This is the cleanest way to do this
val (l, _ :: r) = list.span( _ != 4)
The span function splits the list at the first value not matching the condition, and the de-structuring on the left-hand side removes the matching value from the second list.
This will fail if there is no matching value.
Given a list and a delimiter, in order to split the list in 2:
val list = List(1, 1, 1, 1, 4, 2, 2, 2, 2)
val delimiter = 4
you could use a combination of List.indexOf, List.take and List.drop:
val splitIdx = list.indexOf(delimiter)
List(list.take(splitIdx), list.drop(splitIdx + 1))
you could use List.span which splits the list into a tuple given a predicate:
list.span(_ != delimiter) match { case (l1, l2) => List(l1, l2.tail) }
in order to produce:
List(List(1, 1, 1, 1), List(2, 2, 2, 2))
scala> val l = List(1,1,1,1,4,2,2,2,2)
l: List[Int] = List(1, 1, 1, 1, 4, 2, 2, 2, 2)
scala> l.splitAt(l.indexOf(4))
res0: (List[Int], List[Int]) = (List(1, 1, 1, 1),List(4, 2, 2, 2, 2))
def convert(list: List[Int], separator: Int): List[List[Int]] = {
#scala.annotation.tailrec
def rec(acc: List[List[Int]], listTemp: List[Int]): List[List[Int]] = {
if (listTemp.isEmpty) acc
else {
val (l, _ :: r) = listTemp.span(_ != separator)
rec(acc ++ List(l), r)
}
}
rec(List(), list)
}

For-comprehensions of dynamic depth in Scala

I am writing a code that needs to generate all combinations of integer sequences which are (element-wise) within bounds of two other integer sequences. The code will be probably more readable than the above explanation:
def combinations(startingCounts: List[Int], endingCounts: List[Int] ) = for(
a <- startingCounts(0) to endingCounts(0);
b <- startingCounts(1) to endingCounts(1);
c <- startingCounts(2) to endingCounts(2)
) yield List(a, b, c)
combinations(List(0,7,3), List(1,7,5))
//^returns Vector(List(0, 7, 3), List(0, 7, 4), List(0, 7, 5), List(1, 7, 3), List(1, 7, 4), List(1, 7, 5))
The above code works as expected, but it has two problems:
It only works correctly with lists of a certain length. This isn't really an issue with my use-case, but in general it is.
The code length is proportional to the list length I need to take care of. In my case the length is 6 and I have a for-comprehension with 6 generators.
My question is: what is the best way of implementing the same function in a way that it works with all "bound list" lenghts? By "best" I mean correct, simple enough, and preferably not (much) slower than the original.
How about this?
def combinations(startingCounts: List[Int], endingCounts: List[Int] ) : IndexedSeq[List[Int]] = {
if(startingCounts.isEmpty)
IndexedSeq(Nil)
else
for{
ns <- combinations(startingCounts.tail, endingCounts.tail)
n <- startingCounts.head to endingCounts.head
} yield
n :: ns
}
Here is my initial solution. It looks OK, but I wonder if it can be done better.
import scala.annotation.tailrec
type SLInt = IndexedSeq[List[Int]]
def combinations2(startingCounts: List[Int], endingCounts: List[Int] ): SLInt = {
#tailrec
def inner(acc: SLInt, startingCounts: List[Int], endingCounts: List[Int]): SLInt = {
(startingCounts, endingCounts) match {
case (sh :: st, eh :: et) if (sh <= eh) => {
val newAcc = for(
ls <- acc;
last <- (sh to eh)
) yield (last :: ls)
inner(newAcc, st, et)
}
case (Nil, Nil) => acc
case _ => throw new IllegalArgumentException()
}
}
inner(IndexedSeq(List()), startingCounts.reverse, endingCounts.reverse)
}
combinations2(List(0,7,3), List(1,7,5))
//res3: SLInt = Vector(List(0, 7, 3), List(1, 7, 3), List(0, 7, 4), List(1, 7, 4), List(0, 7, 5), List(1, 7, 5))
The order of the results is different, but that doesn't make a difference. I am performing the List.reverse to avoid using List append operation and to use prepend instead, which should be constant time.

Scala - convert List of Lists into a single List: List[List[A]] to List[A]

What's the best way to convert a List of Lists in scala (2.9)?
I have a list:
List[List[A]]
which I want to convert into
List[A]
How can that be achieved recursively? Or is there any other better way?
List has the flatten method. Why not use it?
List(List(1,2), List(3,4)).flatten
> List(1,2,3,4)
.flatten is obviously the easiest way, but for completeness you should also know about flatMap
val l = List(List(1, 2), List(3, 4))
println(l.flatMap(identity))
and the for-comprehension equivalent
println(for (list <- l; x <- list) yield x)
flatten is obviously a special case of flatMap, which can do so much more.
Given the above example, I'm not sure you need recursion. Looks like you want List.flatten instead.
e.g.
scala> List(1,2,3)
res0: List[Int] = List(1, 2, 3)
scala> List(4,5,6)
res1: List[Int] = List(4, 5, 6)
scala> List(res0,res1)
res2: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6))
scala> res2.flatten
res3: List[Int] = List(1, 2, 3, 4, 5, 6)
If your structure can be further nested, like:
List(List(1, 2, 3, 4, List(5, 6, List(7, 8))))
This function should give you the desire result:
def f[U](l: List[U]): List[U] = l match {
case Nil => Nil
case (x: List[U]) :: tail => f(x) ::: f(tail)
case x :: tail => x :: f(tail)
}
You don't need recursion but you can use it if you want:
def flatten[A](list: List[List[A]]):List[A] =
if (list.length==0) List[A]()
else list.head ++ flatten(list.tail)
This works like flatten method build into List. Example:
scala> flatten(List(List(1,2), List(3,4)))
res0: List[Int] = List(1, 2, 3, 4)
If you want to use flatmap, here is the the way
Suppose that you have a List of List[Int] named ll, and you want to flat it to List,
many people already gives you the answers, such as flatten, that's the easy way. I assume that you are asking for using flatmap method. If it is the case, here is the way
ll.flatMap(_.map(o=>o))

verifying a probability distribution with variable arguments sums to 1

I was wondering how you would write a method in Scala that takes a function f and a list of arguments args where each arg is a range. Suppose I have three arguments (Range(0,2), Range(0,10), and Range(1, 5)). Then I want to iterate over f with all the possibilities of those three arguments.
var sum = 0.0
for (a <- arg(0)) {
for (b <- arg(1)) {
for (c <- arg(2)) {
sum += f(a, b, c)
}
}
}
However, I want this method to work for functions with a variable number of arguments. Is this possible?
Edit: is there any way to do this when the function does not take a list, but rather takes a standard parameter list or is curried?
That's a really good question!
You want to run flatMap in sequence over a list of elements of arbitrary size. When you don't know how long your list is, you can process it with recursion, or equivalently, with a fold.
scala> def sequence[A](lss: List[List[A]]) = lss.foldRight(List(List[A]())) {
| (m, n) => for (x <- m; xs <- n) yield x :: xs
| }
scala> sequence(List(List(1, 2), List(4, 5), List(7)))
res2: List[List[Int]] = List(List(1, 4, 7), List(1, 5, 7), List(2, 4, 7), List(2
, 5, 7))
(If you can't figure out the code, don't worry, learn how to use Hoogle and steal it from Haskell)
You can do this with Scalaz (in general it starts with a F[G[X]] and returns a G[F[X]], given that the type constructors G and F have the Traverse and Applicative capabilities respectively.
scala> import scalaz._
import scalaz._
scala> import Scalaz._
import Scalaz._
scala> List(List(1, 2), List(4, 5), List(7)).sequence
res3: List[List[Int]] = List(List(1, 4, 7), List(1, 5, 7), List(2, 4, 7), List(2
, 5, 7))
scala> Seq(some(1), some(2)).sequence
res4: Option[Seq[Int]] = Some(List(1, 2))
scala> Seq(some(1), none[Int]).sequence
res5: Option[Seq[Int]] = None
That would more or less do the job (without applying f, which you can do separately)
def crossProduct[A](xxs: Seq[A]*) : Seq[Seq[A]]
= xxs.foldLeft(Vector(Vector[A]())){(res, xs) =>
for(r <- res; x <- xs) yield r :+ x
}
You can then just map your function on that. I'm not sure it's a very efficient implementation though.
That's the answer from recursive perspective. Unfortunately, not so short as others.
def foo(f: List[Int] => Int, args: Range*) = {
var sum = 0.0
def rec(ranges: List[Range], ints: List[Int]): Unit = {
if (ranges.length > 0)
for (i <- ranges.head)
rec(ranges.tail, i :: ints)
else
sum += f(ints)
}
rec(args.toList, List[Int]())
sum
}
Have a look at this answer. I use this code for exactly this purpose. It's slightly optimized. I think I could produce a faster version if you need one.