Scala型铸造功能结果

时间:2015-01-12 12:29:05

标签: scala

我是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]]类型... 感谢。

2 个答案:

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

结果类型将尽可能具体,这可能是您想要的。但是当然如果你想扩大它,你可以使用类型归属,或者只是通过更宽泛的类型声明接收结果的变量。