Scalaの特性をミックスするには、新しいオブジェクトを作成する必要がありますか?

StackOverflow https://stackoverflow.com/questions/1810305

  •  05-07-2019
  •  | 
  •  

質問

Scalaでは、コレクションで groupBy()を呼び出すと、値がコレクションである Map が返されますが、 MultiMap が必要です。変換を行う最も簡単な方法は何ですか?新しい MultiMap を作成してすべてをコピーすることを避けることができますか?

役に立ちましたか?

解決

" Scalaの特性をミックスするために新しいオブジェクトを作成する必要がありますか?" 「はい」です。オブジェクトのラッピングと暗黙的な変換により、多少の痛みを最小限に抑えることができます。


特定の問題については、groupBy(...)を変更可能なマップを変更可能なセットに返すように強制できませんでした。これを「MapProxy with MultiMap」でラップする必要があります。ただし、独自の" groupBy"のバージョンを実装するには、コード行が多すぎません:

package blevins.example

object App extends Application {

  implicit def multiMapable[B](c: Iterable[B]) = new {
    def groupByMM[A](f: B => A) = {
      import scala.collection.mutable._
      val ret = new HashMap[A,Set[B]] with MultiMap[A,B]
      for (e <- c) { ret.addBinding(f(e), e) }
      ret
    } 
  }

  val c = List(1,2,3,4,5,6,7,8,9)
  val mm = c.groupByMM { i => if (i < 5) "alpha" else "beta" }
  mm.addBinding("alpha",12)
  println(mm) // Map(beta -> Set(5, 7, 6, 9, 8), alpha -> Set(3, 1, 4, 2, 12))

}

補遺

値をコピーせずに、既存のMap [String、Set [Int]]をMultiMapにラップする例を次に示します。

object App extends Application {
  import scala.collection.mutable._
  val seed: Map[String,Set[Int]] = Map("even" -> Set(2,4,6), "odd" -> Set(1,3,5))

  val multiMap = new MapProxy[String,Set[Int]] with MultiMap[String,Int] {
    val self = seed
  }

  multiMap.addBinding("even", 8)
  println(multiMap) // Map(odd -> Set(5, 3, 1), even -> Set(6, 8, 4, 2))
}

シードマップは可変である必要があり、groupBy(...)は不変マップを返すため、groupBy(...)の結果に対してこれを行うことはできないことに注意してください。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top