代码之家  ›  专栏  ›  技术社区  ›  RameshVel

在Scala中创建动态增长数组的最佳方法是什么?

  •  31
  • RameshVel  · 技术社区  · 14 年前

    我想动态地将项添加到数组中。但是Scala数组和列表似乎没有提供任何动态添加项的方法,因为它们具有不可变的特性。

    所以我决定使用列表数据类型来利用这个 :: 实现这一点的方法。我的代码是这样的

    var outList = List(Nil)
    val strArray = Array("ram","sam","bam")
    
    for (str<-strArray)
         outList = str :: outList
    

    虽然它以某种方式工作,但问题是新字符串被预先附加到列表中。但理想的要求是数据的顺序。是的,我知道你在想什么,你可以把最后的结果列表倒过来,得到原来的顺序。但问题是这是一个巨大的数组。我相信这不是一个解决办法,尽管它解决了问题。我相信应该有一个简单的方法来解决这个问题。。。

    变量

    我该怎么做?

    理想情况下,我希望在Scala中实现类似的功能(下面是 C# (代码)

    List<int> ls = new List<int>();    
    for (int i = 0; i < 100; i++)
        ls.Add(i);
    
    7 回复  |  直到 7 年前
        1
  •  35
  •   Alexey Romanov    14 年前

    不,Scala数组只是Java数组,所以

    val arr = Array(1,2)
    
    arr(0) = 3 // arr == Array(3, 2)
    

    但是就像java(和C/C++ +C等)数组一样,你不能改变。 大小 数组的一部分。

    所以您需要另一个集合,它由一个数组支持,但允许调整大小。Scala的合适收藏是 scala.collection.mutable.ArrayBuffer , java.util.ArrayList 用Java等语言。

    List 而不是 Array scala.collection.mutable.ListBuffer

        2
  •  4
  •   Enrico Susatyo    14 年前

    追根溯源:

    如果您仍然想使用list,有几种方法可以将一个项目预先添加到list中。你能做的是(是的,上面的部分仍然是错误的):

    scala> var outList : List[String] = Nil
    outList: List[String] = List()
    
    scala> val strArray = Array("a","b","c")
    strArray: Array[java.lang.String] = Array(a, b, c)
    
    scala> for(s <- strArray)      
         | outList = outList :+ s
    
    scala> outList
    res2: List[String] = List(a, b, c)
    

    注意操作符。如果您想附加,您应该使用s+:outList。

    谁说Scala编程不好玩

    另外,也许你想让它们不变的原因是速度。对于不可变的数据类型,处理大数据将更加有效。我说得对吗?

        3
  •  4
  •   michael.kebe    14 年前

    如果您想使用一个可变的缓冲区,正如前面提到的。看起来是这样的:

    scala> var outList = scala.collection.mutable.Buffer[String]()
    outList: scala.collection.mutable.Buffer[String] = ArrayBuffer()
    
    scala> for(str<-strArray) outList += str                          
    
    scala> outList
    res10: scala.collection.mutable.ListBuffer[String] = ListBuffer(ram, sam, bam)
    

    strArray . 例如:

    strArray map(_.toUpperCase) foreach(println)
    
        4
  •  4
  •   olle kullberg    14 年前

    如果要使用不可变结构,可以使用++方法:

    scala> val orgList = List(1,2,3)
    orgList: List[Int] = List(1, 2, 3)
    
    scala> val list2Add = List(4,5,6)
    list2Add: List[Int] = List(4, 5, 6)
    
    scala> val newList = orgList ++ list2Add
    newList: List[Int] = List(1, 2, 3, 4, 5, 6)
    

    如果您想在元素上做更多的工作,而不仅仅是添加它们,您可以使用更高阶的函数:

    val newList = orgList ++ list2Add.map(_ * 2)
    newList: List[Int] = List(1, 2, 3, 8, 10, 12)
    

    或使用for循环:

    val newList = orgList ++ {for(x <- list2Add) yield 2*x}
    

    或者可以创建一些递归循环:

    def addAll(toList: List[Int], fromList: List[Int]): List[Int] =
      fromList match {
        case x :: tail => addAll(2*x :: toList, tail)
        case Nil => toList
      }
    
    val newList = addAll(orgList, list2Add )
    

    但在这种情况下,添加元素的顺序将相反:

    List(12, 10, 8, 1, 2, 3)
    

    如果希望在处理列表时获得更好的性能,最好反转结果,而不是在最后添加新元素。在列表的末尾添加元素并不好:-)

        5
  •  3
  •   retronym    14 年前

    好吧,有几件事需要澄清。

    这是错误的,您正在创建一个单元素列表,其中包含一个空列表:

    scala> var outList = List(Nil) 
    outList: List[object Nil] = List(List())
    

    Nil

    scala> var outList: List[String] = Nil
    outList: List[String] = List()
    

    或者,如果您愿意:

    scala> var outList = List[String]() 
    outList: List[String] = List()
    

    如果没有更多的上下文,就很难知道“动态”是什么意思。最好将示例代码编写为:

    scala> val strArray = Array("ram","sam","bam")
    strArray: Array[java.lang.String] = Array(ram, sam, bam)
    
    scala> strArray toList
    res0: List[java.lang.String] = List(ram, sam, bam)
    

    scala.mutable.Buffer .

        6
  •  2
  •   Aaron    14 年前

    如果要创建新集合,可以使用yield关键字:

    val outlist = for(i <- 0 to 100) yield i
    

    或:

    val arrList = "Some" :: "Input" :: "List" :: Nil
    val outlist = for ( i <- arrList ) yield i
    

    从技术上讲,在上述两个示例中,outlist都是Seq,因此如果需要List的某些方法,可能需要调用toList方法。

        7
  •  0
  •   whoisthis    6 年前

    我们可以按建议使用ArrayBuffer。 但是,我已经创建了一个简单的程序,它不接受int数组的任何参数,它将允许您输入数字,最后我们将显示它们。

    val arraySize = scala.io.StdIn.readLine().toInt
      val arr = new ArrayBuffer[Int]() ++ (1 to arraySize).map{
        i =>
          scala.io.StdIn.readLine().toInt
      }
      println(arr.mkString(","))