/ / scala карта събират еквивалентни на groovy карта събира - scala, groovy

скалата карта събира еквивалентна на groovy карта събира - scala, groovy

Искам списък с всички стойности за конкретен ключ в вложената карта. Имам супер красив пример в 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)