Искам списък с всички стойности за конкретен ключ в вложената карта. Имам супер красив пример в groovy както по-долу.
class HashTableExperiment {
static def retailPackages = [
"package1": [
"items" : ["white shirt", "blue pants", "blue shirt"],
"shippingDate": new Date(2016, 10, 28)
],
"package2": [
"items" : ["blue shirt", "brown pants", "blue converse"],
"shippingDate": new Date(2016, 11, 23)
]
]
static def itemInventory() {
retailPackages.entrySet().collect {it.value.items}.flatten()
}
static def main(String[] args) {
itemInventory().each {
println(it)
}
}
}
продукция
white shirt
blue pants
blue shirt
blue shirt
brown pants
blue converse
Искам това изпълнение в скала, не можех да го направя естествено като в groovy.
object MapExperiment {
val retailPackages = Map(
"package1" -> Map(
"items" -> List("white shirt", "blue pants", ""),
"shippingDate" -> new Date(2016, 10, 28)
),
"package2" -> Map(
"items" -> List("blue shirt", "brown pants", "blue converse"),
"shippingDate" -> new Date(2016, 11, 23)
)
)
def itemInventory(): Unit = {
val items = retailPackages.map(p => p._2).map(it => it("items"))
items.flatten
}
}
Получавам следната компилация грешка в изравняване
Error:(25, 11) No implicit view available from java.io.Serializable => scala.collection.GenTraversableOnce[B].
items.flatten
^
Също така моето предположение беше тип items
променлива трябва да бъде List[List[String]]
, nope, скала компилатор вика, че трябва да бъде Iterable[Serializable]
, Поне, Iterable[Iterable[String]]
има смисъл, но откъде идва Serializable от?
Когато му дам вид,
val items : Iterable[Serializable] = retailPackages.map(p => p._2).map(it => it("items"))
Казва Iterable[Serializable] doesn"t conform to Iterable[Serializable]
Отговори:
1 за отговор № 1Можете да принудите артикулите от Serializable
да се List[String]
:
@ MapExperiment.retailPackages("package1")("items")
res11: Object with java.io.Serializable = List(white shirt, blue pants, )
@ MapExperiment.retailPackages("package1")("items").asInstanceOf[List[String]]
res12: List[String] = List("white shirt", "blue pants", "")
Тогава flatten
върши работа:
@ MapExperiment.retailPackages map { _._2 } map { _("items").asInstanceOf[List[String]] } flatten
res13: collection.immutable.Iterable[String] = List("white shirt", "blue pants", "", "blue shirt", "brown pants", "blue converse")
или в една карта:
@ MapExperiment.retailPackages map { _._2("items").asInstanceOf[List[String]] } flatten
res14: collection.immutable.Iterable[String] = List("white shirt", "blue pants", "", "blue shirt", "brown pants", "blue converse")
0 за отговор № 2
Това е причината за retailPackages е смесен тип:
Map(
String -> Map (
String -> List,
String -> Date
)
)
така че, когато картите "елементите", то не може да изведе елементи тип, можете да използвате case
за да съответства на елементи Тип:
retailPackages.map(i => i._2("items")).flatMap{case l: List[String] => l}
Предложението е: използвайте класа на случай за елемента си, като:
case class MyObject(items: List[String], shippingDate: Date)
val retailPackages = Map(
"package1" -> MyObject(List("white shirt", "blue pants", ""), new Date(2016, 10, 28))
,
"package2" -> MyObject(List("blue shirt", "brown pants", "blue converse"),new Date(2016, 11, 23))
)
retailPackages.flatMap(i => i._2.items)