Что лучший способ состоит в том, чтобы создать динамично растущий массив в Scala?

Я хотел добавить объекты динамично в массив. Но это кажется массивами Scala, и списки не предоставляют методов для добавления объектов динамично из-за неизменной природы.

Таким образом, я решил использовать тип данных Списка для использования этого:: метод для достижения этого. Мой код похож на это

var outList = List(Nil)
val strArray = Array("ram","sam","bam")

for (str<-strArray)
     outList = str :: outList

Хотя это работает в некотором роде, проблемой являются новые строки, предварительно добавляются в список. Но идеальное требование является порядком данных. Да, я знаю то, что Вы думаете, можно инвертировать список конечного результата для получения первоначального заказа. Но проблема, это - огромный массив. И я полагаю, что это не решение, хотя это решает проблему. Я полагаю, что должен быть простой способ решить это...

И моя причина взламывания Scala состоит в том, чтобы изучить функциональный способ кодировать. Наличие var (изменяемый тип) и заполнение списка на лету кажутся мне, не функциональный способ решить вещи.

Как я могу сделать это?

Идеально, я хочу достигнуть чего-то вроде этого в Scala (ниже кода C#)

List ls = new List();    
for (int i = 0; i < 100; i++)
    ls.Add(i);

33
задан Luke Williams 22 June 2017 в 15:23
поделиться

6 ответов

Но похоже, что Scala Arrays & Lists не предоставляет никаких методов для динамического добавления элементов из-за неизменяемой природы.

Ну, нет. Массивы Scala - это просто массивы Java, поэтому они являются изменяемыми:

val arr = Array(1,2)

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

Но так же, как и массивы Java (и C/C++/C#/etc.), вы не можете изменить размер массива.

Поэтому вам нужна другая коллекция, которая основана на массиве, но позволяет изменять размер. Подходящей коллекцией в Scala является scala.collection.mutable.ArrayBuffer, java.util.ArrayList в Java и т.д.

Если вы хотите получить в итоге List вместо Array, используйте scala.collection.mutable.ListBuffer вместо этого.

33
ответ дан 27 November 2019 в 18:26
поделиться

Переход к ответу ретронима:

Если вы все еще хотите использовать список, есть несколько способов добавить элемент в список. Что вы можете сделать (да, верхняя часть все еще неправильная):

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. Возможно, причина, по которой вы захотите сделать их неизменяемыми, - это скорость. Обработка больших данных будет более эффективной с неизменяемыми типами данных. Я прав?

4
ответ дан 27 November 2019 в 18:26
поделиться

Если вы хотите использовать изменяемый буфер, как упоминалось ретронимом. Это выглядит так:

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
ответ дан 27 November 2019 в 18:26
поделиться

Если вы хотите создать новую коллекцию, вы можете использовать ключевое слово 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 в обоих приведенных выше примерах, поэтому вы может потребоваться вызвать метод toList для него, если вам нужны некоторые из методов List.

2
ответ дан 27 November 2019 в 18:26
поделиться

Если вы хотите работать с неизменяемыми структурами, вы можете использовать метод ++:

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 loop:

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
ответ дан 27 November 2019 в 18:26
поделиться

Хорошо, есть несколько вещей, которые нужно прояснить.

Это неверно, вы составляете список из одного элемента, содержащий пустой список:

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 .

3
ответ дан 27 November 2019 в 18:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: