Какой самый стандартный (/ краткий) способ сравнить списки, чтобы проверить, есть ли у них частичные совпадения? - PullRequest
0 голосов
/ 23 апреля 2019

Предположим, у меня есть класс case, который выглядит следующим образом

case class CaseClassX(a: String, b: Int, c: Boolean)

и два списка одинаковой длины, содержащие этот класс дел.

Каков самый стандартный (/ краткий) способ сравнения списков, чтобы проверить, есть ли у них частичные совпадения? (Предполагая, что списки отсортированы)

т.е. Сравнение проводится только по b и c, но не по

Успешный случай:

  Seq(
    CaseClassX("some text1", 1, true),
    CaseClassX("some text2", 2, false),
    CaseClassX("some text3", 3, true)
  )

Выше должно соответствовать следующее

 Seq(
    CaseClassX("some text4", 1, true),
    CaseClassX("some text5", 2, false),
    CaseClassX("some text6", 3, true)
  )

Неудачный случай:

  Seq(
    CaseClassX("some text1", 1, true),
    CaseClassX("some text2", 2, false),
    CaseClassX("some text3", 3, true)
  )

Вышеуказанное не должно совпадать со следующим

 Seq(
    CaseClassX("some text4", 1, true),
    CaseClassX("some text5", 2, true),
    CaseClassX("some text6", 3, true)
  )

Ответы [ 2 ]

2 голосов
/ 23 апреля 2019

Вы можете zip обе последовательности, а затем просто использовать forall:

def partialMatch(seq1: Seq[CaseClassX], seq2: Seq[CaseClassX]): Boolean = (seq1, seq2)
  .zipped
  .forall {
     case (CaseClassX(_, b1, c1),CaseClassX(_, b2, c2)) => b1 == b2 && c1 == c2
  }
2 голосов
/ 23 апреля 2019

В верхней части головы я бы написал общий метод, подобный следующему:

// this is good practice
import scala.collection.immutable.Seq

def matches[A, B](xs: Seq[A], ys: Seq[B])(comparer: (A, B) => Boolean): Boolean = xs.zip(ys).forall { case (x, y) => comparer(x, y) }

case class CaseClassX(a: String, b: Int, c: Boolean)

val xs = List(CaseClassX("hi", 42, false), CaseClassX("hello", 1, true)
val ys = List(CaseClassX("hi", 42, true), CaseClassX("hello", 1, false))

matches(xs, ys)((x, y) => x.a == y.a && x.b == y.b) //true
matches(xs, ys)((x, y) => x.a == y.c && x.c == y.c) //false

Я отредактировал его, чтобы оно стало еще более общим. Не нужно ограничивать второй параметр Seq[A], поэтому я добавил другой параметр типа и сделал его Seq[B].

...