0

私はこのような抽象化を構築しました:

class Thing(val messages: Map[String, Seq[String]]) { 
  def and(that: Thing): Thing = {
    new Thing(this.messages ++ that.messages)
  }
}

thisの のマップを のマップString -> Seq[String]とマージする必要がありthatます。

これは、これを行うために私が考えることができる最良の方法です:

def and(that: Thing): Thing = {
  val keys = this.messages.keys ++ that.messages.keys
  val tuples = keys map {
    case key: String =>
      val theseMessages = this.messages.getOrElse(key, Seq[String]())
      val thoseMessages = that.messages.getOrElse(key, Seq[String]())
      (key, theseMessages ++ thoseMessages)
  }
  new Thing(tuples.toMap)
}
4

3 に答える 3

1

Scalazライブラリには、この関数(semigroup append) 演算子が含まれています。よりも具体的なコレクション タイプ、つまりセミグループ インスタンスを持つ|+|コレクション タイプを選択する必要があることに注意してください。SeqList

import scalaz._, Scalaz._

class Thing(val messages: Map[String, List[String]]) { 
  def and(that: Thing): Thing =
    new Thing(this.messages |+| that.messages)
}

の半群インスタンスを定義しThing、演算子を使用して|+|を結合することもできますThing

case class Thing(val messages: Map[String, List[String]])

implicit val ThingSemigroup = new Semigroup[Thing] {
  def append(t1: Thing, t2: => Thing) = new Thing(t1.messages |+| t2.messages)
}

Thing(Map("foo" -> List("bar"))) |+| Thing(Map("foo" -> List("baz")))
// Thing(Map(foo -> List(bar, baz)))
于 2012-10-21T09:59:23.243 に答える
0

コメントでリンクした回答のより具体的な、わずかに変更されたバージョンで、アプローチが少し明確になる可能性があります。

def and(that: Thing): Thing = {
  new Thing(this.messages.foldLeft(that.messages) { case (out, (keyToAdd, valuesToAdd)) =>
    out ++ Map(keyToAdd -> out.get(keyToAdd).map(_ ++ valuesToAdd).getOrElse(valuesToAdd))
  })
}

また、マップの 1 つをループしないという利点もあります。

于 2012-10-21T03:45:51.077 に答える