我是Scala的新手。我想找出一种打印不可变数据的方法,该数据是带有键的映射,键是字符串的元组,值是双精度值:
Map(
("ZZ1", "A") -> 3.5,
("ZZ2", "C") -> 2.3,
("ZZ3", "D") -> 2.8,
("ZZ1", "D") -> 3.0,
("ZZ2", "D") -> 5.9
)
想法是最终得到类似于没有值的零填充表格的打印结果(下图中的示例)。
如何执行这种避免循环的方法?
预先感谢
答案 0 :(得分:2)
也许是这样?
val data = Map(
("ZZ1", "A") -> 3.5,
("ZZ2", "C") -> 2.3,
("ZZ3", "D") -> 2.8,
("ZZ1", "D") -> 3.0,
("ZZ2", "D") -> 5.9
)
val (rows, cols) = {
val (r, c) = data.keys.unzip
(r.toList.sorted, c.toList.sorted)
}
val table =
("" +: cols).map("%5s".format(_)).mkString + "\n" +
rows.map { r =>
"%5s".format(r) + cols.map { c =>
" %4.1f".format(data.getOrElse((r, c), 0.0))
}
.mkString
}.mkString("\n")
println(table)
礼物:
A C D
ZZ1 3.5 0.0 3.0
ZZ2 0.0 2.3 5.9
ZZ3 0.0 0.0 2.8
我并没有尝试使所有空间看起来都与图像中的完全一样,有更好的工具(TeX,CSS)。
答案 1 :(得分:1)
鉴于您的数据结构,您可以按元组的第一列进行分组,然后按如下所示手动提取值。
您有一个循环可用于分组(内部循环可循环访问分组的值,这意味着O(n^2)
),循环到每个循环可打印(O(n)
)。
val data = Map(("ZZ1", "A") -> 3.5,
("ZZ2", "C") -> 2.3,
("ZZ3", "D") -> 2.8,
("ZZ1", "D") -> 3.0,
("ZZ2", "D") -> 5.9)
val group = data.groupBy{case (k, v) => k._1}.map { case (k, v) =>
k -> v.map { case (k1, v1) => k1._2 -> v1 }
}
val Separator = " "
println(s"${Separator}A ${Separator}B${Separator}C${Separator}D")
group.foreach {case (k, v) =>
println(
k + " " +
v.get("A").getOrElse(0.0) + Separator +
v.get("B").getOrElse(0.0) + Separator +
v.get("C").getOrElse(0.0) + Separator +
v.get("D").getOrElse(0.0))
}
结果:
A B C D
ZZ1 3.5 0.0 0.0 3.0
ZZ3 0.0 0.0 0.0 2.8
ZZ2 0.0 0.0 2.3 5.9
这里是运行示例-https://scastie.scala-lang.org/prayagupd/ZaK6hk2gRbSd6Yq1op7N1Q