scala - reales - matriz bcg excel
¿Cuál es la mejor manera de crear una matriz de crecimiento dinámico en Scala? (6)
Pero parece que Scala Arrays & Lists no proporciona ningún método para agregar elementos dinámicamente debido a la naturaleza inmutable.
Bueno no. Los arreglos Scala son solo arreglos Java, por lo que son mutables:
val arr = Array(1,2)
arr(0) = 3 // arr == Array(3, 2)
Pero al igual que las matrices de Java (y C / C ++ / C # / etc.), No puede cambiar el tamaño de una matriz.
Así que necesita otra colección, que está respaldada por una matriz, pero permite cambiar el tamaño. Una colección adecuada en Scala es scala.collection.mutable.ArrayBuffer
, java.util.ArrayList
en Java, etc.
Si desea obtener una List
lugar de una Array
al final, use en scala.collection.mutable.ListBuffer
lugar scala.collection.mutable.ListBuffer
.
Quería agregar elementos dinámicamente en una matriz. Pero parece que las matrices y listas de Scala no proporcionan ningún método para agregar elementos dinámicamente debido a la naturaleza inmutable.
Así que decidí usar el tipo de datos de lista para hacer uso de este :: método para lograrlo. Mi código se parece a esto
var outList = List(Nil)
val strArray = Array("ram","sam","bam")
for (str<-strArray)
outList = str :: outList
Aunque funciona de alguna manera, el problema es que las nuevas cadenas se añaden previamente a la lista. Pero el requisito ideal es el orden de los datos. Sí, sé lo que está pensando, puede revertir la lista de resultados finales para obtener el pedido original. Pero el problema es que es una gran variedad. Y creo que no es una solución, aunque resuelve el problema. Creo que debería haber una manera simple de resolver esto ...
Y mi razón para hackear a Scala es aprender la forma funcional de codificación. Me parece que tener var (tipo mutable) y poblar la lista sobre la marcha no es una forma funcional de resolver las cosas.
¿Cómo puedo hacerlo?
Idealmente, quiero lograr algo como esto en Scala (debajo del código C# )
List<int> ls = new List<int>();
for (int i = 0; i < 100; i++)
ls.Add(i);
Está bien, hay algunas cosas que aclarar.
Esto es incorrecto, estás haciendo una lista de un elemento, que contiene una lista vacía:
scala> var outList = List(Nil)
outList: List[object Nil] = List(List())
Nil
es la lista vacía.
scala> var outList: List[String] = Nil
outList: List[String] = List()
O, si lo prefieres:
scala> var outList = List[String]()
outList: List[String] = List()
Sin más contexto, es difícil saber qué quiere decir con "dinámicamente". Tu código de ejemplo se escribiría mejor como:
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)
Si desea una colección mutable que pueda crecer y manejar eficientemente las operaciones de scala.mutable.Buffer
e inserción, puede usar scala.mutable.Buffer
.
Si desea trabajar con estructuras inmutables, puede utilizar el método ++:
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)
Si desea trabajar más en los elementos que solo agregarlos, puede usar funciones de orden superior:
val newList = orgList ++ list2Add.map(_ * 2)
newList: List[Int] = List(1, 2, 3, 8, 10, 12)
O con un bucle for:
val newList = orgList ++ {for(x <- list2Add) yield 2*x}
O podrías crear un bucle recursivo:
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 )
pero en este caso el ordenamiento de los elementos agregados se invertirá:
List(12, 10, 8, 1, 2, 3)
Si desea rendimiento cuando trabaja con listas, es mejor revertir el resultado que intentar agregar nuevos elementos al final. Agregar elementos al final de una lista no es bueno :-)
Si desea utilizar un búfer mutable, como se menciona en las siglas. Se parece a esto:
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)
De todos modos, quizás sea mejor hacer directamente las cosas que quieres hacer con el strArray
. P.ej:
strArray map(_.toUpperCase) foreach(println)
Si está buscando crear una nueva colección, puede usar la palabra clave de rendimiento:
val outlist = for(i <- 0 to 100) yield i
O:
val arrList = "Some" :: "Input" :: "List" :: Nil
val outlist = for ( i <- arrList ) yield i
Técnicamente, outlist es un Seq en los dos ejemplos anteriores, por lo que es posible que deba usar el método toList si necesita alguno de los métodos de List.
Yendo tras la respuesta de retronym:
Si aún desea utilizar la lista, hay algunas maneras de anteponer un elemento a la lista. Lo que puedes hacer es (sí, la parte superior sigue siendo incorrecta):
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)
Tenga en cuenta el: + operador. Si prefiere agregar, usaría s +: outList.
Ahora, ¿quién dice que programar en Scala no es divertido? ;)
PD: Tal vez la razón por la que querrías hacerlos inmutables es la velocidad. El manejo de datos grandes será más eficiente con tipos de datos inmutables. ¿Estoy en lo cierto?