Preferred way to create a Scala list

后端 未结 10 2557
走了就别回头了
走了就别回头了 2020-12-02 04:31

There are several ways to construct an immutable list in Scala (see contrived example code below). You can use a mutable ListBuffer, create a var list and modif

相关标签:
10条回答
  • 2020-12-02 05:14

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

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

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

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

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

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

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

    0 讨论(0)
  • 2020-12-02 05:14

    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 讨论(0)
  • 2020-12-02 05:21

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

    def listTestD = (0 to 3).toList
    

    or

    def listTestE = for (i <- (0 to 3).toList) yield i
    
    0 讨论(0)
  • 2020-12-02 05:21

    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 讨论(0)
  • 2020-12-02 05:24

    And for simple cases:

    val list = List(1,2,3) 
    

    :)

    0 讨论(0)
  • 2020-12-02 05:26

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

    so for your example, I will do:

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

    before I do:

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

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

    0 讨论(0)
提交回复
热议问题