scala 从序列[B]中减去序列[A]

k2fxgqgv  于 2023-01-20  发布在  Scala
关注(0)|答案(4)|浏览(138)

我有两个类AB,它们都有相同的属性:id和许多其它不同的性质。
如何通过匹配id的来从Seq[B]中减去Seq[A]

ktecyv1j

ktecyv1j1#

只要这两个类的id字段具有相同的类型,这就应该起作用。

val as: Seq[A] = ???
val bs: Seq[B] = ???

val asSet = as.iterator.map(a => a.id).toSet
val substracted: Seq[B] = bs.filterNot(b => asSet(b.id))
t2a7ltrp

t2a7ltrp2#

另一个可行的解决方案:

val seqSub = seqB.filterNot(x => seqA.exists(_.id == x.id))
c8ib6hqw

c8ib6hqw3#

找不到符合我的subtract定义的答案,其中重复的元素不会被过滤,(例如Seq(1,2,2)subtract Seq(2)= Seq(1,2),det0的定义给出了Seq(1),因此将其发布在此处。

trait IntId {
      def id: Int
    }
    
    case class A(id: Int) extends IntId
    
    case class B(id: Int) extends IntId
    
    val seqB = Seq(B(1),B(4),B(7),B(7),B(7))
    
    val seqA = Seq(A(7))

    // BSubtractA =  Seq(B(1),B(4),B(7),B(7)), only remove one instance of id 7
    val BSubtractA = seqA.foldLeft(seqB){
      case (seqBAccumulated, a) =>
        val indexOfA = seqBAccumulated.map(_.id).indexOf(a.id)
        if(indexOfA >= 0) {
          seqBAccumulated.take(indexOfA) ++ seqBAccumulated.drop(indexOfA + 1)
        }
        else {
          seqBAccumulated
        }
    }

是的,这个解决方案有缺点。例如,如果seqA大于seqB,那么它就会遇到空指针(+我还没有将其重构为def)。此外,性能可以通过减少对输入的迭代次数来提高,但是,这满足了我的用例。

x0fgdtte

x0fgdtte4#

会干净得多-

val seqSub = seqB.filterNot(x => seqA.contains(x))

相关问题