我想将项目动态添加到数组中。但是由于不可变的特性,Scala数组和列表似乎没有提供任何动态添加项的方法。
所以我决定使用List数据类型来使用这个 :: 方法来实现这一点。我的代码看起来像这样
var outList = List(Nil)
val strArray = Array("ram","sam","bam")
for (str<-strArray)
outList = str :: outList
虽然它以某种方式工作,但问题是新的字符串被预先附加到列表中。但理想的要求是数据的顺序。是的,我知道你在想什么,你可以反转最终结果列表以获得原始订单。但问题是它是一个巨大的阵列。我相信它不是一个解决方案,虽然它解决了这个问题。我相信应该有一个简单的方法来解决这个问题......
我破解Scala的原因是学习编码的功能方式。拥有 var (可变类型)并在运行中填充列表似乎不是解决问题的功能方法。
我该怎么做?
理想情况下,我希望在Scala中实现类似的功能(在C#代码下面)
List<int> ls = new List<int>();
for (int i = 0; i < 100; i++)
ls.Add(i);
答案 0 :(得分:32)
但似乎Scala Arrays&amp;由于不可变性,列表不提供任何动态添加项的方法。
嗯,不。 Scala Arrays只是Java数组,因此它们 可变:
val arr = Array(1,2)
arr(0) = 3 // arr == Array(3, 2)
但就像Java(和C / C ++ / C#/ etc。)数组一样,你不能改变数组的大小。
所以你需要另一个由数组支持的集合,但允许调整大小。 Scala中的合适集合是scala.collection.mutable.ArrayBuffer
,Java中的java.util.ArrayList
等等。
如果您想在最后获得List
而不是Array
,请改用scala.collection.mutable.ListBuffer
。
答案 1 :(得分:4)
继续使用反语:
如果您仍想使用列表,可以通过几种方法将项目添加到列表中。你可以做的是(是的,最重要的部分仍然是错误的):
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中编程并不好玩? ;)
P.S。也许你想让它们变得不可变的原因是速度。使用不可变数据类型处理大数据会更有效。我是对的吗?
答案 2 :(得分:4)
如果您想使用可变缓冲区,请提及。它看起来像这样:
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
做你想做的事情。 E.g:
strArray map(_.toUpperCase) foreach(println)
答案 3 :(得分:4)
如果要使用不可变结构,可以使用++方法:
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)
如果在使用列表时需要性能,最好反转结果而不是尝试最后添加新元素。最后在列表中添加元素是好的: - )
答案 4 :(得分:3)
好的,有一些事情需要澄清。
这是错误的,你要制作一个包含空列表的单元素列表:
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)
如果你想要一个可以增长并有效处理prepend,append和insert操作的可变集合,你可以使用scala.mutable.Buffer
。
答案 5 :(得分:2)
如果您要创建新集合,可以使用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方法。
答案 6 :(得分:0)
我们可以按照建议使用ArrayBuffer。 但是,我创建了一个简单的程序,该程序不使用int数组的任何参数,它可以让您输入数字,最后我们将它们显示出来。
from datetime import date
from dateutil.relativedelta import relativedelta
def AgeTest(dob):
age = relativedelta(date.today(), dob)
print (age)
return age.years, age.months, age.days