0

I want to match a Array whose first element is 0 or 1 or Null, below is the example:

def getTheta(tree: Node, coding: Array[Int]): Array[Double] = {
    val theta = coding.take(coding.length - 1) match {
        case Array() => tree.theta
        case Array(0,_) => getTheta(tree.right.asInstanceOf[Node],coding.tail)
        case Array(1,_) => getTheta(tree.left.asInstanceOf[Node],coding.tail)
    }
    theta
}

the tree class definition is :

sealed trait Tree

case class Leaf(label: String, popularity: Double) extends Tree

case class Node(var theta: Array[Double], popularity: Double, left: Tree, right: Tree) extends Tree

Actually I know that Array(0,__) or Array(1,_) is wrong, but what I care about is only the first element of the Array, and how can I match it?

Can someone help me?

Yang
  • 612
  • 1
  • 6
  • 18
  • Avoid using asInstanceOf as not safe – Pavel May 26 '17 at 07:30
  • Thanks! @Cyäegha, I didn't see that question before, actually it is the same to my problem. – Yang May 26 '17 at 07:34
  • usually you should return Option[Node] and then use patterns matching to see what result is – Pavel May 26 '17 at 07:38
  • Thanks, I will modify it and one more question, why asInstanceOf is not safe? – Yang May 26 '17 at 07:52
  • Here is some comments on this: https://stackoverflow.com/questions/6686992/scala-asinstanceof-with-parameterized-types As per my understanding asInstanceOf just will throw an exception if object is Null and this is not "idiomatic" way of dealing with objects: – Pavel May 26 '17 at 08:00

1 Answers1

2

you can use varags in Array to achieve this.

coding.take(coding.length - 1) match {
   case Array(0, _ *)  => getTheta(tree.left.asInstanceOf[Node],coding.tail)
   case Array(1, _ *)  => getTheta(tree.right.asInstanceOf[Node],coding.tail)
   case Array() =>  getTheta(tree.right.asInstanceOf[Node],coding.tail)
}

Other options are

  • converting Array to list

    coding.take(coding.length - 1).toList match {
      case 1 :: tail => getTheta(tree.right.asInstanceOf[Node],coding.tail)
      case 0 :: tail => getTheta(tree.left.asInstanceOf[Node],coding.tail)
      case Nil =>  getTheta(tree.left.asInstanceOf[Node],coding.tail)
    }
    
  • use if guards in pattern match as below

    coding.take(coding.length - 1) match {
        case x if x.head == 0 => getTheta(tree.right.asInstanceOf[Node],coding.tail)
        case x if x.head == 1 => getTheta(tree.left.asInstanceOf[Node],coding.tail)
        case Array() =>  getTheta(tree.left.asInstanceOf[Node],coding.tail)
    }
    
rogue-one
  • 11,259
  • 7
  • 53
  • 75