我是Scala编程的新手,但在Java方面有多年的经验。
Java中有一个简单的问题让我在Scala中挣扎。
我有一些来自数据库的记录
+----+--------+--------------+------+
| id | level | subLevel | name |
+----+--------+--------------+------+
| 3 | level1 | subLevel1 | three|
| 4 | level2 | subLevel1 | four |
| 5 | level2 | subLevel1 | five |
+----+--------+--------------+------+
需要像这样总结到Map
{
"level1": {
"subLevel1": [
{
"id": "3",
"name": "three"
}
]
},
"level2": {
"subLevel1": [
{
"id": "4",
"name": "four"
},
{
"id": "5",
"name": "five"
}
]
}
}
如果是在Java中,也许我可以这样解决:
public JSONObject centerMap() {
List<Center> centerList = centerService.getAllCenter();
Map<String, Map<String, List<Map<String, String>>>> centerMap = new HashMap<String, Map<String, List<Map<String, String>>>>();
for (Center center : centerList) {
Map<String, List<Map<String, String>>> subLevelList = centerMap.get(center.getLevel());
if (subLevelList == null)
subLevelList = new HashMap<String, List<Map<String, String>>>();
List<Map<String, String>> names = subLevelList.get(center.getSubLevel());
if (names == null)
names = new ArrayList<Map<String, String>>();
final Center c = center;
names.add(new HashMap<String, String>(){{
put("name", c.getName());
put("id", String.valueOf(c.getId()));
}});
subLevelList.put(center.getSubLevel(), names);
centerMap.put(center.getLevel(), subLevelList);
}
return JSONObject.fromObject(centerMap);
}
我真的不知道在Scala中做到这一点的最佳方法
但几乎可以肯定不是scala.collection.mutable.Map
答案 0 :(得分:1)
考虑一个案例类,例如
case class Entry(id: Int, level: String, subLevel: String, name: String)
和一系列条目,
val entries = Array(
Entry(3, "level1", "subLevel1", "three"),
Entry(4, "level2", "subLevel1", "four"),
Entry(5, "level2", "subLevel1", "five"))
然后考虑将此类值分组为level
和subLevel
,如下所示,
entries.groupBy { case Entry(id,level,subLevel,name) => (level,subLevel)}
因此
Map((level1,subLevel1) -> Array(Entry(3,level1,subLevel1,three)),
(level2,subLevel1) -> Array(Entry(4,level2,subLevel1,four),
Entry(5,level2,subLevel1,five)))
答案 1 :(得分:1)
以榆树的答案为基础。
当制作更大且更永久的地图时,我倾向于通过在同一地图中添加几个不同的groupBy来扩展elm提出的模式。
case class LevelKey(level:String)
case class NameKey(name:String)
case class SublevelKey(level:String,subLevel:String)
val finalMap={
val bySublevel=xs.groupBy(v=>SublevelKey(v.level,v.subLevel))
val bylevel=xs.groupBy(v=>LevelKey(v.level))
val byName=xs.groupBy(v=>NameKey(v.name))
bySublevel++byLevel++byName
}
这样,您可以从同一个地图按级别,子级别或名称访问地图。使用案例类作为键使访问代码非常易读。
finalMap.get(LevelKey("level1"))
finalMap.get(NameKey("five"))
finalMap.get(SubLevelKey("level1", "subLevel1"))
案例类的hashcode()和equals()方法非常快。根据我的经验,与在地图中使用地图的模式相比,此模式可以导致速度增加。