Scala - 将一个键映射到不同类型的多个值

时间:2017-09-19 20:43:54

标签: scala

所以我试图在Scala中使用数据。我现在遇到了障碍。我正在将一个文本文件读入包含列表的程序中,创建一个用于读取每个标题的case类。我已经设法将(String,String)映射到double,但我希望将字符串映射到(string,double)。相关代码在这里:

def averageofactions (): Map[(String,String),  Double] = {

  datafile.groupBy(d => (d.user, d.typeofaction))
.mapValues(averageof => averageof.map(_.amount).sum /averageof.length)
 }

它给了我想要的东西(特定用户的特定动作的平均数量)但格式化以便它给出(UserID,Action) - >平均,而我只想要一个像

这样的列表

UserID1:

行动1 - >平均

行动2 - >平均

等等。我知道可能最好的方法是通过更改它来返回Map [String,(String,Double)],或者可能是multimap / hashmap,但我不确定如何解决这个问题。我试过了:

def modifiedaverage (): Map[String, (List[String], Double)] = {

  datafile.groupBy(d => (d.user))
.mapValues(averageof => (averageof.map(_.typeofaction),     averageof.map(_.amount).sum/averageof.length))

}

但这里的输出完全是奇怪的。我怎样才能重写这个功能给我想要的东西?

1 个答案:

答案 0 :(得分:2)

如果您希望输出的类型为Map[String, Map[String, Double]](地图地图),则可以按actionoftype对每个分组结果user进行分组:

def averageofactions(): Map[String, Map[String, Double]] = {
  datafile.groupBy(_.user)
    .mapValues(_.groupBy(_.typeofaction)
      .mapValues(averageof => averageof.map(_.amount).sum /averageof.length))
}

或者,如果你想要"压扁"将其转换为(String, String, Double)元组的序列(而非地图),您可以:

def averageofactions(): Seq[(String, String, Double)] = {
  datafile.groupBy(averageof => (averageof.user, averageof.typeofaction))
    .mapValues(averageof => averageof.map(_.amount).sum /averageof.length)
    .map { case ((user, action), avg) => (user, action, avg) }.toSeq
}