[ACCEPTED]-Preferred way to create a Scala list-scala

Accepted answer
Score: 109

ListBuffer is a mutable list which has constant-time 21 append, and constant-time conversion into 20 a List.

List is immutable and has constant-time prepend 19 and linear-time append.

How you construct 18 your list depends on the algorithm you'll 17 use the list for and the order in which 16 you get the elements to create it.

For instance, if 15 you get the elements in the opposite order 14 of when they are going to be used, then 13 you can just use a List and do prepends. Whether 12 you'll do so with a tail-recursive function, foldLeft, or 11 something else is not really relevant.

If 10 you get the elements in the same order you 9 use them, then a ListBuffer is most likely a preferable 8 choice, if performance is critical.

But, if 7 you are not on a critical path and the input 6 is low enough, you can always reverse the list 5 later, or just foldRight, or reverse the input, which is 4 linear-time.

What you DON'T do is use a List and append 3 to it. This will give you much worse performance 2 than just prepending and reversing at the 1 end.

Score: 65

And for simple cases:

val list = List(1,2,3) 

:)

0

Score: 23

Uhmm.. these seem too complex to me. May 1 I propose

def listTestD = (0 to 3).toList

or

def listTestE = for (i <- (0 to 3).toList) yield i
Score: 5

You want to focus on immutability in Scala 6 generally by eliminating any vars. Readability 5 is still important for your fellow man so:

Try:

scala> val list = for(i <- 1 to 10) yield i
list: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

You 4 probably don't even need to convert to a 3 list in most cases :)

The indexed seq will 2 have everything you need:

That is, you can 1 now work on that IndexedSeq:

scala> list.foldLeft(0)(_+_)
res0: Int = 55
Score: 2

I always prefer List and I use "fold/reduce" before 9 "for comprehension". However, "for comprehension" is 8 preferred if nested "folds" are required. Recursion 7 is the last resort if I can not accomplish 6 the task using "fold/reduce/for".

so for 5 your example, I will do:

((0 to 3) :\ List[Int]())(_ :: _)

before I do:

(for (x <- 0 to 3) yield x).toList

Note: I 4 use "foldRight(:\)" instead of "foldLeft(/:)" here 3 because of the order of "_"s. For a version 2 that does not throw StackOverflowException, use 1 "foldLeft" instead.

Score: 2

Note: This answer is written for an old version of Scala.

The Scala collection classes are going to 5 be redesigned as of Scala 2.8, so be prepared 4 to change the way you create lists very 3 soon.

What is the forward compatible way 2 of creating a List? I have no idea since 1 I haven't read the 2.8 docs yet.

A PDF document describing the proposed changes of the collection classes

Score: 2

Using List.tabulate, like this,

List.tabulate(3)( x => 2*x )
res: List(0, 2, 4)

List.tabulate(3)( _ => Math.random )
res: List(0.935455779102479, 0.6004888906328091, 0.3425278797788426)

List.tabulate(3)( _ => (Math.random*10).toInt )
res: List(8, 0, 7)

0

Score: 1

As a new scala developer i wrote small test 3 to check list creation time with suggested 2 methods above. It looks like (for ( p <- ( 0 1 to x ) ) yield p) toList the fastest approach.

import java.util.Date
object Listbm {

  final val listSize = 1048576
  final val iterationCounts = 5
  def getCurrentTime: BigInt = (new Date) getTime

  def createList[T] ( f : Int => T )( size : Int ): T = f ( size )

  // returns function time execution
  def experiment[T] ( f : Int => T ) ( iterations: Int ) ( size :Int ) : Int  = {

    val start_time = getCurrentTime
    for ( p <- 0 to iterations )  createList ( f ) ( size )
    return (getCurrentTime - start_time) toInt

  }

  def printResult ( f:  => Int ) : Unit = println ( "execution time " + f  )

  def main( args : Array[String] ) {


    args(0) match {

      case "for" =>  printResult ( experiment ( x => (for ( p <- ( 0 to x ) ) yield p) toList  ) ( iterationCounts ) ( listSize ) )
      case "range"  =>  printResult ( experiment ( x => ( 0 to x ) toList ) ( iterationCounts ) ( listSize ) )
      case "::" => printResult ( experiment ( x => ((0 to x) :\ List[Int]())(_ :: _) ) ( iterationCounts ) ( listSize ) )
      case _ => println ( "please use: for, range or ::\n")
    }
  }
}
Score: 0

just an example that uses collection.breakOut

scala> val a : List[Int] = (for( x <- 1 to 10 ) yield x * 3)(collection.breakOut)
a: List[Int] = List(3, 6, 9, 12, 15, 18, 21, 24, 27, 30)

scala> val b : List[Int] = (1 to 10).map(_ * 3)(collection.breakOut)
b: List[Int] = List(3, 6, 9, 12, 15, 18, 21, 24, 27, 30)

0

More Related questions