Scala - 如何在scala中初始化地图地图?

时间:2018-03-19 11:47:45

标签: scala scala-collections

尝试学习Scala。我想初始化地图地图 我的Java代码看起来像这样:

(*使用computeIfAbsent)

 private static void initMap() {
    mapAdd(new App("ID_A", "Site1", "app_AAA", "A_A_A_A"));
    mapAdd(new App("ID_B", "Site1", "app_BBB", "B_B_B_B"));
    mapAdd(new App("ID_C", "Site2", "app_CCC", "C_C_C_C"));
    mapAdd(new App("ID_D", "Site2", "app_DDD", "D_D_D_D"));
}

private static void mapAdd(App app) {
    map.computeIfAbsent(app.siteId, x -> new HashMap<>()).put(app.name, app);
}

我的Scala看起来像这样

val app1 = new AppKey("ID_A", "Site1", "app_AAA", "A_A_A_A")
val app2 = new AppKey("ID_B", "Site1", "app_BBB", "B_B_B_B")
val app3 = new AppKey("ID_C", "Site2", "app_CCC", "C_C_C_C")
val app4 = new AppKey("ID_D", "Site2", "app_DDD", "D_D_D_D")

val nameToAppKey1 = mutable.Map[String, AppKey](app1.name -> app1)
nameToAppKey1 += (app2.name -> app2)

val nameToAppKey2 = mutable.Map[String, AppKey](app3.name -> app3)
nameToAppKey2 += (app4.name -> app4)

map += ("Site1" -> nameToAppKey1)
map += ("Site2" -> nameToAppKey2)

看起来它是由一名爪哇难民写的 在Scala中初始化地图地图的最佳做法是什么?

2 个答案:

答案 0 :(得分:1)

初始化数据......

//whatever your case class is
case class AppKey(id: String, site: String, appName: String, name: String)

val app1 = AppKey("ID_A", "Site1", "app_AAA", "A_A_A_A")
val app2 = AppKey("ID_B", "Site1", "app_BBB", "B_B_B_B")
val app3 = AppKey("ID_C", "Site2", "app_CCC", "C_C_C_C")
val app4 = AppKey("ID_D", "Site2", "app_DDD", "D_D_D_D")

val apps = Seq(app1, app2, app3, app4)

如果您尝试按网站对应用进行分组,则可以指定您需要的内容,例如:

Map (
  "Site2" -> apps.filter(appKey => appKey.site == "Site2"),
  "Site1" -> apps.filter(appKey => appKey.site == "Site1")
)

或以单行方式进行:

apps.groupBy(_.site)

这两种方法都提供以下输出(为便于阅读而格式化):

Map(
  Site2 -> List(AppKey(ID_C,Site2,app_CCC,C_C_C_C),AppKey(ID_D,Site2,app_DDD,D_D_D_D)),
  Site1 -> List(AppKey(ID_A,Site1,app_AAA,A_A_A_A),AppKey(ID_B,Site1,app_BBB,B_B_B_B))
)

如果你想通过ID之类的东西进一步分组,你可以这样做:

apps.groupBy(_.site).mapValues(_.groupBy(_.id))

给出以下输出:

Map(
  Site2 -> 
    Map(
      ID_D -> List(AppKey(ID_D,Site2,app_DDD,D_D_D_D)),
      ID_C -> List(AppKey(ID_C,Site2,app_CCC,C_C_C_C))
    ),
  Site1 ->
    Map(
      ID_A -> List(AppKey(ID_A,Site1,app_AAA,A_A_A_A)),
      ID_B -> List(AppKey(ID_B,Site1,app_BBB,B_B_B_B))
    )
)

对于更复杂的示例,您可以继续添加.mapValues(_.groupBy(_.{...})),或者通过类似于第一个示例的方式准确指定要分组的内容。请注意,在Scala中,您并不需要指定new关键字 - 在大多数情况下,无论如何都是隐含的(与分号相同)。

答案 1 :(得分:0)

试试这个,可能会有所帮助

find

filter替换为find以获取值列表(在地图中)

结果将是:

res0: scala.collection.immutable.Map[String,Option[AppKey]] = Map(ID_D -> Some(AppKey(ID_D,Site2,app_DDD,D_D_D_D)), ID_A -> Some(AppKey(ID_A,Site1,app_AAA,A_A_A_A)), ID_C -> Some(AppKey(ID_C,Site2,app_CCC,C_C_C_C)), ID_B -> Some(AppKey(ID_B,Site1,app_BBB,B_B_B_B)))

filter

res0: scala.collection.immutable.Map[String,List[AppKey]] = Map(Site2 -> List(AppKey(ID_C,Site2,app_CCC,C_C_C_C), AppKey(ID_D,Site2,app_DDD,D_D_D_D)), Site1 -> List(AppKey(ID_A,Site1,app_AAA,A_A_A_A), AppKey(ID_B,Site1,app_BBB,B_B_B_B)))

{{1}}