从Seq [B]

时间:2019-05-22 14:40:17

标签: scala

我有两个班AB。它们都具有相同的属性:id和许多其他不同的属性。

如何通过匹配Seq[A]Seq[B]中减去id

3 个答案:

答案 0 :(得分:4)

只要两个类的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))

答案 1 :(得分:3)

另一个可行的解决方案:

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

答案 2 :(得分:1)

找不到与我的减法定义相匹配的答案,其中不过滤重复元素,(例如 Seq(1,2,2) 减去 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)。此外,性能还可以改进以减少对输入的迭代次数,但是,这满足了我的用例。