1

1つのキーが常に存在するが、もう1つのキーと値のペアが動的である2要素のマップを返す変更できないAPIを使用しており、それらをケースクラスにアンパックしようとしています。以下のコードは機能しますが、本当に醜いです:

case class Foo(name: String, key: String, value: String)

def fooFromMap(item: Map[String, String]): Option[Foo] = {
  var name: String = null
  var key: String = null
  var value: String = null
  item.foreach { 
    case ("name", v) => name = v
    case (k, v) => key = k; value = v
  }
  if(name != null && key != null && value != null) Some(Foo(name, key, value))
  else None
}

これを行うためのより良い方法はありますか?

4

3 に答える 3

3

以下は同等であり、より慣用的です。

def fooFromMap(item: Map[String, String]): Option[Foo] = for {
  name   <- item get "name"
  (k, v) <- (item - "name").headOption
} yield Foo(name, k, v)

またはが空の場合、結果は空になります。それ以外の場合は、必要な結果が得られitem get "name"ます。(item - "name").headOptionFoo

于 2012-12-31T18:23:32.413 に答える
2

私が正しく理解していれば、Mapは常にnameキーとゼロまたはもう1つのキーと値のペアを持っていますよね?そうである場合は、次のことができます。

def fooFromMap(map: Map[String, String]) =
  map.get("name").map { name =>
    val (key, value) = (map - "name").head
    Foo(name, key, value)
  }

に2番目のペアがあるかどうかも確認する必要がある場合Map(ない場合は戻るNone)、次のようにします。

def fooFromMap(map: Map[String, String]) = for {
  name <- map.get("name")
  (key, value) <- (map - "name").headOption
} yield Foo(name, key, value)

2番目のスニペットはより慣用的でありfor、Scalaの強力な理解を利用しているため、私は2番目のスニペットを好む傾向があります。

于 2012-12-31T18:32:34.357 に答える
0
def fooFromMap(map: Map[String, String]): Option[Foo] = {
  val data = m.find(_._1 != "name").getOrElse (null, null)
  Foo(m.getOrElse("name", null), data._1, data._2) match { 
    case f: Foo if (f.name != null && f.key != null && f.value != null) => Some(f)
    case _ => None
  }
}
于 2012-12-31T20:19:42.007 に答える