我是scala的新手,无法理解这个类型相关的问题。
尝试将一个将键值元组列表(键可能是非唯一的)转换为属于使用额外“列”列表选择的特定键的聚合值元组列表的函数。 out需要具有Array [Array [Any]]的签名:
示例:
输入:
[("k1", 10), ("k2", 15), ("k1", 18), ("k3", 23), ("k1", 13), ("k2", 1)]
列:
COLUMNS = ["k1", "k2"]
输出:
[[10, 18, 13], [15, 1]]
我的尝试看起来像:
val COLUMNS = Array("k1", "k2")
def convert(result: Array[Tuple2[String, Any]]): Array[Array[Any]] = {
val grouped = result.groupBy(cell => cell._1)
val columns = grouped.mapValues(cell => cell.map(column => column._2))
val tuples = COLUMNS.map(col => columns.getOrElse(col, Array()))
return tuples
}
我收到了以下错误:
<console>:21: error: type mismatch;
found : scala.collection.mutable.ArraySeq[Array[_]]
required: Array[Array[Any]]
return tuples
有人可以帮忙吗?注意我最后需要Array [Array [Any]]类型... 感谢。
答案 0 :(得分:0)
你应该只为空数组明确指定Any
,因为默认情况下它有Nothing
类型(我还删除了不必要的返回和非常规的大写锁定,简化的lambdas):
val Columns = Array("k1", "k2")
def convert(result: Array[(String, Any)]): Array[Array[Any]] = {
val grouped = result.groupBy(_._1)
val columns = grouped.mapValues(_.map(_._2))
Columns.map(columns.getOrElse(_, Array[Any]()))
}
scala> convert(Array(("k1", 10), ("k2", 15), ("k1", 18), ("k3", 23), ("k1", 13), ("k2", 1)))
res2: Array[Array[Any]] = Array(Array(10, 18, 13), Array(15, 1))
答案 1 :(得分:0)
groupBy
是此类工作的关键:
val kvs = Array(("k1", 10), ("k2", 15), ("k1", 18), ("k3", 23), ("k1", 13), ("k2", 1))
scala> Array("k1", "k2") map kvs.groupBy(_._1) map (_ map (_._2))
res16: Array[Array[Int]] = Array(Array(10, 18, 13), Array(15, 1))
请注意,我们正在利用Map
可以从键到值用作函数的事实。在这种情况下groupBy
的结果是从密钥到包含它的元组的Map
;我们map
Map
(使用它作为一个函数)超过感兴趣的键来获取它们的元组,然后从它们中提取值。
如果你所使用的某些键可能根本不存在于输入中,你可以使用withDefaultValue
来表示在这种情况下应该返回一个空数组:
scala> Array("k1", "k2", "k9") map (kvs.groupBy(_._1) withDefaultValue Array()) map (_ map (_._2))
res17: Array[Array[Int]] = Array(Array(10, 18, 13), Array(15, 1), Array())
结果类型将尽可能具体,这可能是您想要的。但是当然如果你想扩大它,你可以使用类型归属,或者只是通过更宽泛的类型声明接收结果的变量。