模式匹配案例类,所有案例具有相同的返回值

问题描述 投票:0回答:1

我是 Scala 新手,我看到人们访问案例类的唯一方法是使用模式匹配。

我最近用以下代码解决了霍夫曼编码问题


  abstract class TreeNodes 
  case class Leaf(weight: Int, value: String) extends TreeNodes
  case class Node(weights: Int, left: TreeNodes, right: TreeNodes) extends TreeNodes

  // P50
  def huffman(freq: List[(String,Int)]): List[(String,String)] = {
    def makeNode(left: TreeNodes, right: TreeNodes): Node = 
      (left,right) match 
        case (Leaf(w1,_),Leaf(w2,_)) => Node(w1 + w2, left,right)
        case (Node(w1,_,_),Leaf(w2,_)) => Node(w1 + w2, left ,right)
        case (Leaf(w1,_), Node(w2,_,_)) => Node(w1 + w2, left, right)
        case (Node(w1,_,_), Node(w2,_,_)) => Node(w1 + w2, left, right)

    def makeLeaves(freq: List[(String,Int)]): List[TreeNodes] = freq.map((s: String, i: Int) => Leaf(i,s))

    def makeTree(nodes: List[TreeNodes]): List[TreeNodes] = {
      if nodes.size == 1 then nodes else {
        val sortedNodes = nodes.sortBy(_ match {case Leaf(w,_) => w; case Node(w,_,_) => w})
        makeTree(sortedNodes.appended(makeNode(sortedNodes.head,sortedNodes.tail.head)).drop(2))
      }
    }

    def traverseTree(node: TreeNodes, acc: String): List[(String, String)] = {
      node match  
        case Leaf(w, s) => List((s,acc))
        case Node(w, left, right) => traverseTree(left, acc + "0") ::: traverseTree(right, acc + "1")
    }
    traverseTree(makeTree(makeLeaves(freq)).head, "").sortBy(_._1)
  }

输入和输出应该像这样:

scala> huffman(List(("a", 45), ("b", 13), ("c", 12), ("d", 16), ("e", 9), ("f", 5)))
res0: List[String, String] = List((a,0), (b,101), (c,100), (d,111), (e,1101), (f,1100))

代码正确并产生所需的输出。但是,我想将

makeNode
函数重构为更干净的版本,因为所有情况都有相同的返回值。

我想要一个更简洁的版本。 有没有办法为不同的案例类创建公共字段或以任何其他方式访问案例类而无需模式匹配?

scala pattern-matching case-class scala-3
1个回答
2
投票

只需在公共接口中声明公共方法即可,在本例中,将

def weight: Int
val weight: Int
添加到基类中。

在 Scala 2.x 中:

sealed abstract class TreeNodes {
  def weight: Int
}
case class Leaf(weight: Int, value: String) extends TreeNodes
case class Node(weight: Int, left: TreeNodes, right: TreeNodes) extends TreeNodes

//...

  def makeNode(left: TreeNodes, right: TreeNodes): Node =
    Node(left.weight + right.weight, left,right)

在 Scala 3.x 中:

enum TreeNodes:
  case Leaf(weight: Int, value: String)
  case Node(weight: Int, left: TreeNodes, right: TreeNodes)
  def weight: Int

但如果您希望其余代码按原样工作,请记住导入

Leaf
Node
import TreeNodes._

© www.soinside.com 2019 - 2024. All rights reserved.