在Scala中合并两个具有不同类型参数的集合
我需要实现一个类,它基本上包含一个键和一个值对,其中值是一个元组序列。该元组包含一个对象在Scala中合并两个具有不同类型参数的集合,scala,polymorphism,Scala,Polymorphism,我需要实现一个类,它基本上包含一个键和一个值对,其中值是一个元组序列。该元组包含一个对象SynthesizedMetricTag,以及一个类型参数a,该参数具有数值上下文绑定,因此实际上是一个k/v序列,其中v需要是一个数字 case class Cohort[A : Numeric](index:Any,values:Seq[(SynthesizedMetricTag,A)]) 当我必须实现一个合并这个类的两个实例的函数时,问题就来了。更具体地说,当我必须将类型a的序列与类型B的序列合并时,
SynthesizedMetricTag
,以及一个类型参数a,该参数具有数值
上下文绑定,因此实际上是一个k/v序列,其中v需要是一个数字
case class Cohort[A : Numeric](index:Any,values:Seq[(SynthesizedMetricTag,A)])
当我必须实现一个合并这个类的两个实例的函数时,问题就来了。更具体地说,当我必须将类型a的序列与类型B的序列合并时,问题就出现了。这两种类型都有一个数值的上下文范围,所以我的想法是,最后我得到一个队列[C]
与上下文绑定并合并A
和B
类型序列的所有K/V对,而不重复任何键
case class Cohort[A : Numeric](index:Any,values:Seq[(SynthesizedMetricTag,A)]) {
def merge[B : Numeric, C:Numeric](that:Cohort[B]):Cohort[C] =
if(this.index != that.index) throw new Exception("Unable to merge Cohorts. Criteria is not the same")
else {
val b = new ArrayBuffer[(SynthesizedMetricTag,C)]()
val seen = new mutable.HashSet[SynthesizedMetricTag]()
for (x <- this.values; y <- that.values){
if(!seen(x._1)){
b+= x
seen += x._1
}
if(!seen(y._1)){
b+= y
seen += y._1
}
}
Cohort(this.index,b.toSeq)
}
}
因此,我尝试了以下方法:
case class Cohort[A : Numeric](index:Any,values:Seq[(SynthesizedMetricTag,A)]) {
def merge[B : Numeric, C:Numeric](that:Cohort[B]):Cohort[C] =
if(this.index != that.index) throw new Exception("Unable to merge Cohorts. Criteria is not the same")
else {
val b = new ArrayBuffer[(SynthesizedMetricTag,C)]()
val seen = new mutable.HashSet[SynthesizedMetricTag]()
for (x <- this.values; y <- that.values){
if(!seen(x._1)){
b+= x.asInstanceOf[(SynthesizedMetricTag,C)]
seen += x._1
}
if(!seen(y._1)){
b+= y.asInstanceOf[(SynthesizedMetricTag,C)]
seen += y._1
}
}
Cohort(this.index,b.toSeq)
}
}
病例组[A:数值](索引:任意,值:Seq[(综合计量表,A)]){
def merge[B:Numeric,C:Numeric](即:队列[B]):队列[C]=
如果(this.index!=that.index)抛出新异常(“无法合并队列。条件不相同”)
否则{
val b=新阵列缓冲[(合成计量表,C)]()
val seen=new mutable.HashSet[SynthesizedMetricTag]()
对于(x1),我将使用从A型和B型到C型的隐式证据来定义该方法
case class Cohort[A <: Numeric](index:Any,values:Seq[(SynthesizedMetricTag,A)]) {
def merge[B <: Numeric, C](that:Cohort[B])(implicit ev1:A=>C, ev2:B=>C):Cohort[C] =
if(this.index != that.index) throw new Exception("Unable to merge Cohorts. Criteria is not the same")
else {
val b = new ArrayBuffer[(SynthesizedMetricTag,C)]()
val seen = new mutable.HashSet[SynthesizedMetricTag]()
for (x <- this.values; y <- that.values){
if(!seen(x._1)){
b += x._1 -> ev1(x._2)
seen += x._1
}
if(!seen(y._1)){
b+= y._1 -> ev2(y._2)
seen += y._1
}
}
Cohort(this.index,b.toSeq)
}
}
病例组群[ac]:组群[C]=
如果(this.index!=that.index)抛出新异常(“无法合并队列。条件不相同”)
否则{
val b=新阵列缓冲[(合成计量表,C)]()
val seen=new mutable.HashSet[SynthesizedMetricTag]()
对于(x ev2(y._2)
所见+=y._1
}
}
队列(本指数,b.toSeq)
}
}
如果A
是Double
,B
是Long
,C
是Byte
,你到底想怎么办?那么C
需要作为类型参数传递,否则编译器不知道C
是什么,所以我希望A
和B
是转换为C
。但我真正想做的是永远不要丢失信息。因此,例如,如果A
是Int
,而B
是Float
,我想A
转换为Float
,并将A
和B
合并到一个集合C
(Float
)。当然这个层次结构不存在,是吗?这就是为什么我需要将结果类型抽象为C并手动确定它。
case class Cohort[A <: Numeric](index:Any,values:Seq[(SynthesizedMetricTag,A)]) {
def merge[B <: Numeric, C](that:Cohort[B])(implicit ev1:A=>C, ev2:B=>C):Cohort[C] =
if(this.index != that.index) throw new Exception("Unable to merge Cohorts. Criteria is not the same")
else {
val b = new ArrayBuffer[(SynthesizedMetricTag,C)]()
val seen = new mutable.HashSet[SynthesizedMetricTag]()
for (x <- this.values; y <- that.values){
if(!seen(x._1)){
b += x._1 -> ev1(x._2)
seen += x._1
}
if(!seen(y._1)){
b+= y._1 -> ev2(y._2)
seen += y._1
}
}
Cohort(this.index,b.toSeq)
}
}