I am having difficulty in phrasing this question so I apologies for the vague sounding title.
I started learning Scala today. I would like to generate a list of elements, and then multiply that list by a factor N, with the result as follows:
List(1, 2, 3, 4) * N -> List(1, 2, 3, 4, 1, 2, 3, 4) (where N = 2)
In Python, I would just do the following which would yield what I am looking for:
my_list = [1, 2, 3, 4] * 2
However, this does not work in Scala.
Try List.fill
List.fill(2)(List(1, 2, 3, 4)).flatten
// : List[Int] = List(1, 2, 3, 4, 1, 2, 3, 4)
or provide extension method to mimic Python, something like
extension (l: List[Int])
def *(n: Int): List[Int] = List.fill(n)(l).flatten
List(1, 2, 3, 4) * 2
// : List[Int] = List(1, 2, 3, 4, 1, 2, 3, 4)
You can do something like that:
val l = List(1, 2, 3, 4)
val n = 2
val result = (1 to n)
.flatMap(_ => l)
.toList
Another option you have is:
val l = List(1, 2, 3, 4)
val length = l.length
List.tabulate(length * n)(i => l(i % length))
Related
I am a beginner to Scala language. In Scala, List is Immutable as per below code:
scala> var list = List(1,2,3,4,5) // List created named ‘ list ’
list: List[Int] = List(1, 2, 3, 4, 5)
scala> 25 :: list // Prepend with Cons( :: ) , But here new list created.
res2: List[Int] = List(25, 1, 2, 3, 4, 5)
scala> list // print ‘ list ’
res3: List[Int] = List(1, 2, 3, 4, 5)
But,
scala> list
res1: List[Int] = List(1, 2, 3, 4, 5)
scala> list :+= 12 // append list with :+=
scala> list
res2: List[Int] = List(1, 2, 3, 4, 5, 12)
In above example, same "list" is appended. Then how list is immutable? It's confusing me. Any one kindly explain to me?
http://daily-scala.blogspot.co.uk/2010/03/implicit-operator.html
:+= is not just appending, it's appending to a new list and reassigning the variable to point to the new list. It's equivalent to list = list + 12.
25 ++ list is making a new list, but not assigning it anywhere.
E.g. for List(1, 1, 1, 2, 3, 3, 4) it would be Set(1, 3), because 1 and 3 are the only elements which occur multiple times.
val s = List(1, 1, 1, 2, 3, 3, 4) // a list with non-unique elements
(s diff s.distinct) toSet // Set(1, 3)
A bit more convoluted but you can avoid having to call toSet.toList, first group the integers:
scala> s.groupBy(identity)
res13: scala.collection.immutable.Map[Int,List[Int]] =
Map(2 -> List(2), 4 -> List(4), 1 -> List(1, 1, 1), 3 -> List(3, 3))
Then collect only the one were the list has length greater as 1:
scala> s.groupBy(identity).collect { case (v, l) if l.length > 1 => v }
res17: scala.collection.immutable.Iterable[Int] = List(1, 3)
If you want a Set just call toSet.
I am new to scala and want to get the following thing done using map, flatMap, and/or for comprehension.
I have a list of lists l = List[List[T]]. For example, l = [[1,2,3],[2,4,6,4],[3,4,6,2,3]]. Note that each list inside l can have varying length.
Now I have val x: List[Int] = [1,2,3] and I want to do some operation on x and l that returns [[1,1,2,3], [1,2,4,6,4], [1,3,4,6,2,3], [2,1,2,3], [2,2,4,6,4], [2,3,4,6,2,3], [3,1,2,3], [3,2,4,6,4], [3,3,4,6,2,3]] (the order of sublists doesn't matter).
I feel like I should use map or flatMap or for-loop to do this but after a long time of trial I can't even get the type correct. Can anyone help me on it?
scala> val ls = List(List(1,2,3),List(2,4,6,4),List(3,4,6,2,3))
ls: List[List[Int]] = List(List(1, 2, 3), List(2, 4, 6, 4), List(3, 4, 6, 2, 3))
scala> val xs: List[Int] = List(1,2,3)
xs: List[Int] = List(1, 2, 3)
scala> for(x <- xs; l <- ls) yield x +: l
res22: List[List[Int]] = List(List(1, 1, 2, 3), List(1, 2, 4, 6, 4), List(1, 3, 4, 6, 2, 3), List(2, 1, 2, 3), List(2, 2, 4, 6, 4), List(2, 3, 4, 6, 2, 3), List(3, 1, 2, 3), List(3, 2, 4, 6, 4), List(3, 3, 4, 6, 2, 3))
x.flatMap(i => l.map(i::_))
This question already has answers here:
Scala Lists of lists of integers
(2 answers)
Closed 8 years ago.
I have a list of list (of type int) and I need to return the first / second column etc depending on the input given as column index. Any ideas on how to access the item of each row of that particular column? I have attempted it but all I came to is using a map function but I don't know how it works exactly. Thanks in advance
One option:
def getColumn[T](list: List[List[T]], column: Int): List[T] = {
list.map(row => row(column))
}
Then:
scala> val l = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
l: List[List[Int]] = List(List(1, 2, 3), List(4, 5, 6), List(7, 8, 9))
scala> getColumn(l, 2)
res0: List[Int] = List(3, 6, 9)
List types can be accessed by index number
scala> val a=List(1,3,5,7,11,13);
a: List[Int] = List(1, 3, 5, 7, 11, 13)
scala> a(1)
res0: Int = 3
scala> a(2)
res1: Int = 5
Multidimensional Lists work too
scala> val a=List(List(1,3,5,7,11,13), List(2,4,6,8,10,12));
a: List[List[Int]] = List(List(1, 3, 5, 7, 11, 13), List(2, 4, 6, 8, 10, 12))
scala> a
res2: List[List[Int]] = List(List(1, 3, 5, 7, 11, 13), List(2, 4, 6, 8, 10, 12))
scala> a(1)
res3: List[Int] = List(2, 4, 6, 8, 10, 12)
scala> a(1)(2)
res4: Int = 6
update to answer your comment, function that takes a List of Lists of Ints and a column number
scala> val a=List(List(1,3,5,7,11,13), List(2,4,6,8,10,12), List(0,10,20,30,40,50,60));
a: List[List[Int]] = List(List(1, 3, 5, 7, 11, 13), List(2, 4, 6, 8, 10, 12), List(0, 10, 20, 30, 40, 50, 60))
scala> def getcol(l: List[List[Int]], n: Int) = (for (i <- l) yield i(n)).toList
getcol: (l: List[List[Int]], n: Int)List[Int]
scala> getcol(a,0)
res17: List[Int] = List(1, 2, 0)
scala> getcol(a,1)
res18: List[Int] = List(3, 4, 10)
val nums = List(List(1,2,3),List(4,5,6))
nums map(_(1)) // gives List(2,5)
Or in a method with colIndex parameter:
def sliceCol[T](ls: List[List[T]], colIndex: Int): List[T] =
ls map(_(colIndex))
sliceCols(1) // same result
I want to use Stream class in scala to repeat a given list infinitely.
For example the list (1,2,3,4,5) I want to create a stream that gives me (1,2,3,4,5,1,2,3,4,5,1,2,3....)
So that I can wrap the take operation. I know this can be implemented in other ways, but I wanna do it this way for some reason, just humor me :)
So the idea is that with this infinite cycle created from some list, I can use take operation, and when it reaches the end of the list it cycles.
How do I make a stream which simply repeats a given list?
Very similar to #Eastsun's, but a bit more intention revealing. Tested in Scala 2.8.
scala> val l = List(1, 2, 3)
l: List[Int] = List(1, 2, 3)
scala> Stream.continually(l.toStream).flatten.take(10).toList
res3: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1)
Alternatively, with Scalaz:
scala> import scalaz._
import scalaz._
scala> import Scalaz._
import Scalaz._
scala> val l = List(1, 2, 3)
l: List[Int] = List(1, 2, 3)
scala> l.toStream.repeat[Stream].join.take(10).toList
res7: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1)
An alternative method is concatenating the .toStream of the input with itself recursively. That is,
scala> def xs: Stream[Int] = List(1, 2, 3).toStream #::: xs
xs: Stream[Int]
scala> xs.take(10).toList
res1: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1)
There is a simple way with Stream#flatten in scala 2.8
Welcome to Scala version 2.8.0.r20542-b20100116020126 (Java HotSpot(TM) Client VM, Java 1.6.0_18).
Type in expressions to have them evaluated.
Type :help for more information.
scala> def cycle[T](seq: Seq[T]) = Stream.from(0).flatten(_ => seq)
cycle: [T](seq: Seq[T])scala.collection.immutable.Stream[T]
scala> cycle(1::2::3::Nil)
res0: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> res0.take(10)
res1: scala.collection.immutable.Stream[Int] = Stream(1, ?)
scala> res0.take(10).toList
res2: List[Int] = List(1, 2, 3, 1, 2, 3, 1, 2, 3, 1)
Here's an implementation which doesn't assume that length is efficient:
def rep[A](seq: Seq[A]) = {
def inner(proj: Seq[A]): Stream[A] = {
if (proj.isEmpty)
inner(seq)
else
Stream.cons(proj.first, inner(proj drop 1))
}
if (seq.isEmpty)
Stream.empty
else
inner(seq)
}
This should run in constant time for any Seq (including List or even Stream) and only imposes a constant time overhead to populate each element. Also, it works even for infinite sequences. So, you can call rep on an infinite Stream and the resulting Stream will be equivalent to the input.
Stolen blatently from the excellent Scala by Example book, chapter 12, and with a few modifications:
def repeatedSeq(idx: Int, lst:Seq[Int]): Stream[Int] = Stream.cons(lst(idx), repeatedSeq((idx + 1)%lst.length, lst))
for(i <- repeatedSeq(1,List(1,1,2,3,5))) println(i)
This works for all Seq types (unless they can't be read from multiple times, of course). Might not be efficient if the .length call is slow. Tested in Scala 2.7.7.