这是参考问题 Possible ways to pass argument of different type to case class
trait Value
// define these in different files if you want
case class Student(value: String) extends Value
case class Employee(value: Double) extends Value
case class Department(value: Int) extends Value
case class Element(key: String, value: Value)
case class Grp (elements: List[Element] = Nil) extends Value {
def add (key: String, value: Value): Grp = Grp(this.elements ++ List(Element(key, value)))
}
Grp()
.add("2", Student("abc"))
.add("3", Employee(100.20))
.add("4", Department(10))
.add("5", Grp().add("2", Student("xyz"))) // nested group
我想在Grp类中添加一个函数
def addSubGroup(group: Grp):Grp=group.elements.foreach(s=>add(s))
但由于return是Unit,因此不会添加元素
更新1
任何人都可以建议我解决这两种方法
我希望我的调用如下所示。我想要包含子组的val subgroup
和addSubGroup将子组添加到组中。
Grp()
.add("2", Student("abc"))
.add("3", Employee(100.20))
.add("4", Department(10))
.addSubGroup("5", Grp().add("2", Student("xyz"))) // nested group
更新2
case class GrpA() extends Grp
和case class GrpB() extends Grp.
这样的群组子类型但是禁止使用案例类继承任何可能的方法来摆脱多个添加调用。
注意:如果可能,请分享没有varargs的解决方案
答案 0 :(得分:1)
您可以在配套对象中使用vararg方法清除多个add
,例如
def apply(elements: (String, Value)*): Grp = Grp(elements.map(Element.tupled).toList)
群组连接可以像通常的++
方法一样实施,如
def ++(that: Grp) = Grp(elements ++ that.elements)
如果您希望您的小组成为某种可迭代的,尊重子群,您可以这样做,扩展Iterable[Element]
并实施
def iterator: Iterator[Element] = elements.iterator.flatMap {
case Element(name, sub: Grp) => sub.iterator
case element => Iterator.single(element)
}
完整Grp
代码示例:
case class Grp(elements: List[Element] = Nil) extends Value with Iterable[Element] {
def add(key: String, value: Value): Grp = Grp(this.elements :+ Element(key, value))
def ++(that: Grp) = Grp(elements ++ that.elements)
def iterator: Iterator[Element] = elements.iterator.flatMap {
case Element(name, sub: Grp) => sub.iterator
case element => Iterator.single(element)
}
}
object Grp {
def apply(elements: (String, Value)*): Grp = Grp(elements.map(Element.tupled).toList)
}
val group = Grp("2" -> Student("abc"),
"3" -> Employee(100.20)) ++
Grp("4" -> Department(10),
"5" -> Grp("2" -> Student("xyz"),
"6" -> Employee(200.3))) // nested group
group.foreach(println)
//Element(2,Student(abc))
//Element(3,Employee(100.2))
//Element(4,Department(10))
//Element(2,Student(xyz))
//Element(6,Employee(200.3))
您仍然可以使用add
语法代替tuple seq factory:
val group = Grp()
.add("2", Student("abc"))
.add("3", Employee(100.20))
.add("4", Department(10))
.add("5", Grp()
.add("2", Student("xyz"))
.add("6", Employee(200.3))) // nested group
答案 1 :(得分:0)
如果允许稍微调整一下类型,我会使用类似的东西:
sealed trait Value
trait BaseValue extends Value
// define these in different files if you want
case class Student(value: String) extends BaseValue
case class Employee(value: Double) extends BaseValue
case class Department(value: Int) extends BaseValue
case class Grp(elements: List[(String, BaseValue)] = Nil,
subGroups: List[(String, Grp)] = Nil) extends Value {
def add(entries: (String, BaseValue)*): Grp = Grp(elements ++ entries, subGroups)
def addSubGroup(entries: (String, Grp)*): Grp = Grp(elements, subGroups ++ entries)
}
Grp()
.add("2" -> Student("abc"), "3" -> Employee(100.20), "4" -> Department(10)) // base elements
.addSubGroup("5" -> Grp().add("2" ->Student("xyz"))) // nested group
这将产生以下结果:
res0: Grp = Grp(List((2,Student(abc)), (3,Employee(100.2)), (4,Department(10))),List((5,Grp(List((2,Student(xyz))),List()))))