Scalaのcollectionのviewを覚えた
RubyのEnumerable#lazyみたいなやつ。
実際の中間処理をその場で実行せずに、forceメソッドが呼ばれたときとか、ループするときに、一気に実行する。
// 中間データができてしまうパターン (1 to 10).map(_ + 1).map(_ + 2) // scala.collection.immutable.IndexedSeq[Int] = Vector(4, 5, 6, 7, 8, 9, 10, 11, 12, 13) // viewで遅延させるパターン (1 to 10).view.map(_ + 1).map(_ + 2) // scala.collection.SeqView[Int,Seq[_]] = SeqViewMM(...)
上のviewの場合は、まだビューオブジェクトのままで、止まっている。
上述のように、forceかループで実際に実行する。
(1 to 10).view.map(_ + 1).map(_ + 2).force //=> Seq[Int] = Vector(4, 5, 6, 7, 8, 9, 10, 11, 12, 13) (1 to 10).view.map(_ + 1).map(_ + 2).foreach(println) //=> 4 //=> 5 ...
無駄な中間データを作らない、という点で、以下のような場合も有効。
(1 to 10000000).filter(_ % 2 == 0).take(10) //=> scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20) // 最初の10個以外は完全に資源の無駄づかい // viewを使うと、 (1 to 10000000).view.filter(_ % 2 == 0).take(10).force //=> scala.collection.immutable.IndexedSeq[Int] = Vector(2, 4, 6, 8, 10, 12, 14, 16, 18, 20) // 内部で融合して、偶数が10個になった時点で、値が返ってくる
Scalaのコレクション系列多くてどれを使っていいのか悩む
PHPだとarray()で済んでたからな…。
とりあえず配列は、線形処理ならList、ランダムアクセスならVectorで、
辞書ならMapを使っておけばいいのでしょうか。。。
scala.collections.immutable
Traversable └Iterable ├Set │├HashSet │├SortedSet ││└TreeSet │├BitSet │└ListSet ├Map │├HashMap │├SortedMap ││└TreeMap │└ListMap └Seq ├IndexedSeq │├Vector │├NumericRange │└Range └LinearSeq ├List ├Stream ├Queue └Stack
scala.collections.mutable
Traversable └Iterable ├Set │├HashSet │├BitSet │├OvservableSet │├SynchronizedSet │├ImmutableSetAdaptor │└LinkedHashSet ├Map │├HashMap │├WeakHashMap │├OpenHashMap │├LinkedHashMap │├ObservableMap │├SynchronizedMap │├ImmutableMapAdaptor │├ListMap │└MultiMap └Seq ├IndexedSeq │├ArraySeq │├StringBuilder │└ArrayBuffer ├Buffer │├OvservableBuffer │├SynchronizedBuffer │└ListBuffer ├Stack │└SynchronizedStack ├ArrayStack ├PriorityQueue │└SynchronizedPriorityQueue └LinearSeq ├MutableList │└Queue │ └SynchronizedQueue ├LinkedList └DoubleLinkedList