読者です 読者をやめる 読者になる 読者になる

AccessViolation Exception

仕事でもはんだづけ、家でもはんだづけ

ScalaのMap->Listで気をつけるべきこと

0から30までの数値を3つずつの組み合わせにまとめたい事案があったとします

scala> (0 to 30).groupBy(_ / 3).map(_._2).toList
res207: List[scala.collection.immutable.IndexedSeq[Int]] = List(
 Vector(0, 1, 2),
 Vector(15, 16, 17),
 Vector(30),
 Vector(3, 4, 5),
 Vector(18, 19, 20),
 Vector(27,28, 29),
 Vector(6, 7, 8),
 Vector(21, 22, 23),
 Vector(9, 10, 11),
 Vector(24, 25, 26),
 Vector(12, 13, 14))

※適当に整形してあります

順番がめちゃくちゃじゃないか(困惑

どうしてこうなった


MapからListになる時に何かあったに違いない

scala> Map(1 -> 'a', 2 -> 'z', 4 -> 'd',3 -> 'c').toList
res202: List[(Int, Char)] = List((1,a), (2,z), (4,d), (3,c))

順番がそのままになる。普通に作られるmapがsortedmap,treemapでない。明示的に扱うなら変換をかませればいいのだが。辞書型といえど(Int,Char)のIntをキーにアクセスしているだけで中身はめちゃくちゃですよとかそういう

groupByで生成されるMapは順番が保証されていない

scala> (0 to 30).groupBy(_ / 3)
res204: scala.collection.immutable.Map[Int,scala.collection.immutable.IndexedSeq[Int]] = Map(0 -> Vector(0, 1, 2),
    5 -> Vector(15, 16, 17),
   10 -> Vector(30), 
    1 -> Vector(3, 4, 5),
    6 -> Vector(18, 19, 20),
    9 -> Vector(27, 28, 29),
    2 -> Vector(6, 7, 8),
    7 -> Vector(21, 22, 23),
    3 -> Vector(9, 10, 11), 
    8 -> Vector(24, 25, 26),
    4 -> Vector(12, 13, 14))

※適当に整形してあります

たいがいMap以外を暗黙に生成してるのはScala歴一ヶ月の俺でもほぼ見たことない

解決策


並び替えてくれる方に一度変換するか、sortつかえsort

できた


scala divide method

元はといえばdivide作りたかっただけなのに、中身にぶっこんでた値がアレな制で余計に複雑にしてしまった感がすごい

追記

groupedでできる

scala divide(grouped)