TreeMap上的map返回一个Map而不是Scala中的TreeMap

时间:2016-01-29 21:02:32

标签: scala treemap

我是Scala的新手,我正在使用像这样的多维键实现TreeMap:

class dimSet (val d:Vector[Int])  extends IndexedSeq[Int] {
  def apply(idx:Int) = d(idx)
  def length: Int = d.length
}
… 
var vals : TreeMap[dimSet, A] = TreeMap[dimSet, A]()(orddimSet)

我有这个方法

def appOp0(t:TreeMap[dimSet,A], t1:TreeMap[dimSet,A], op:(A,A) => A, unop : (A) => A):TreeMap[dimSet,A] = {
  if (t.isEmpty) t1.map((e:Tuple2[dimSet, A]) => (e._1, unop(e._2)))
  else if (t1.isEmpty) t.map((t:Tuple2[dimSet, A]) => (t._1, unop(t._2)))
  else {
    val h = t.head
    val h1 = t1.head
    if ((h._1) == (h1._1)) appOp0(t.tail, t1.tail, op, unop) + ((h._1, op(h._2, h1._2)))
    else if (orddimSet.compare(h._1,h1._1) == 1) appOp0(t, t1.tail, op, unop) + ((h1._1, unop(h1._2)))
    else                   appOp0(t.tail, t1, op, unop) + ((h._1, unop(h._2)))
  }

}

但TreeMaps(第二行和第三行)上的map方法返回一个Map,而不是TreeMap

我尝试使用简单的示例进行repl,我得到了这个:

    scala> val t = TreeMap[dimSet, Double]( (new dimSet(Vector(1,1)), 5.1), (new dimSet(Vector(1,2)), 6.3), (new dimSet(Vector(3,1)), 7.1), (new dimSet(Vector(2,2)), 8.4)) (orddimSet)

scala> val tsq = t.map[(dimSet,Double), TreeMap[dimSet,Double]]((v:Tuple2[dimSet, Double]) => ((v._1, v._2 * v._2)))

<console>:41: error: Cannot construct a collection of type scala.collection.immutable.TreeMap[dimSet,Double] with elements of type (dimSet, Double) based on a collection of type scala.collection.immutable.TreeMap[dimSet,Double].
       val tsq = t.map[(dimSet,Double), TreeMap[dimSet,Double]]((v:Tuple2[dimSet, Double]) => ((v._1, v._2 * v._2)))
                                                               ^

  scala> val tsq = t.map((v:Tuple2[dimSet, Double]) => ((v._1, v._2 * v._2)))
  tsq: scala.collection.immutable.Map[dimSet,Double] = Map((1, 1) -> 26.009999999999998, (1, 2) -> 39.69, (2, 2) -> 70.56, (3, 1) -> 50.41)

我认为CanBuildFrom无法像其他TreeMaps一样构建我的TreeMap,但我找不到原因,¿我该怎么做才能返回TreeMap?

由于

1 个答案:

答案 0 :(得分:0)

问题可能是,当您致电Ordering[dimSet]时,没有可用的隐式map。该通话需要CanBuildFrom,而Ordering则需要隐含TreeMap orddimSet个密钥:see in docs

因此,在调用map之前隐式提供implicit val ev = orddimSet if (t.isEmpty) t1.map((e:Tuple2[dimSet, A]) => (e._1, unop(e._2)))

Ordering[dimSet]

或者,如果您在Ordering的伴随对象中定义隐式dimSet,则可以使object dimSet { implicit val orddimSet: Ordering[dimSet] = ??? // you code here } 始终自动隐式可用:

php /path/to/artisan schedule:run >> /dev/null 2>&1