函数结果的 Scala 类型转换

Scala type casting of function result

我是 scala 的新手,无法解决这个类型相关的问题。

尝试构建一个函数,该函数将键值元组列表(键可能不唯一)转换为属于使用 [=33 的额外列表选择的特定键的聚合值元组列表=]. 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]] 类型...... 谢谢。

你应该只为空数组明确指定Any,因为它在这里默认有Nothing类型(我也删除了不必要的return和非常规的大写锁定,简化的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))

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())

生成的类型将尽可能具体,这可能正是您想要的。但是当然,如​​果你想扩大它,你可以使用类型归属来实现,或者简单地通过使用更宽的类型声明接收结果的变量。