2015-01-22 2 views
1

Здесь я заполнить два списки, где каждый список либо изменяемый или неизменен:Наполнения неизменяемого списка

var mutableList = scala.collection.mutable.MutableList[String]() 
                //> mutableList : scala.collection.mutable.MutableList[String] = MutableList() 
                //| 

    for (a <- 1 to 100) { 
    mutableList += a.toString 
    } 

    println(mutableList.size);      //> 100 
    val immutableList = List[String]()    //> immutableList : List[String] = List() 

    for (a <- 1 to 100) { 
    immutableList :+ a.toString 
    } 

    println(immutableList.size);     //> 0 

При печати размера immutableList его выход равен 0. Это происходит потому, что в пределах цикла для нового создана ссылка, которая не указывает на immutableList? Существует ли функциональный эквивалент заполнения неизменяемого списка из цикла?

+2

'fold' (Left/Right) - это то, что вы ищете (или/tail recursive/recursion). (Или просто 'to [List]' после 'map'.) –

ответ

3

Как ответил Габор в комментарии, вы хотите использовать fold, или даже продолжить работу и yield. Он не объяснил, почему вы получаете размер 0. Причина в том, что immutableList :+ a.toString каждый раз возвращает новый список, который вы не используете. immutableList - это то, что неизменное.

Имейте в виду, что все в Scala является выражением и поэтому возвращает что-то. Таким образом, вы можете превратить ваш регулярный for (который действует как forEach) в понимании, добавив yield ниже

val immutableList = for (a <- 1 to 100) yield a.toString 

Это desugars во что-то вроде:

(1 to 100).map(_.toString) 
+0

В стороне, большинство неизменяемых коллекций scala предлагают метод' newBuilder' на своих сопутствующих объектах, например. 'val lb = List.newBuilder [Int]; ...; val immutableList = lb.result' – Dylan

1

Для полноты метод tabulate позволяет для создания и заполнения неизменяемый List, например, следующим образом,

List.tabulate(100)(a => a.toString) 

или эквивалент

List.tabulate(100)(_.toString) 
Смежные вопросы