Как найти идентичные предметы в источнике - PullRequest
0 голосов
/ 25 декабря 2018

У меня есть такой источник:

1 | red | light | 10
2 | blue | dark | 20
1 | brown | light | 2
1 | red | light | 10
20 | grey | dark | 200

Я хочу выяснить (true / false), есть ли в источнике идентичные предметы.В приведенном выше потоке 1 | red | light | 10 будет идентичным.Этот поток может быть очень большим за 2М записей.Я могу вернуть true, как только идентичный элемент будет найден (т.е. в приведенном выше примере мы можем избежать чтения 20 | grey | dark | 200).

Каков наилучший способ сделать это?Я попытался прочитать весь источник в List(String) и побежал по нему.Это работает нормально, однако для больших источников я начинаю получать ошибку OOM.

val restResult: Future[immutable.Seq[Color]] =
  mySource(ctx)
    .drop(1)
    .via(framing("\n"))
    .map(_.utf8String)
    .map(_.trim)
    .map(s => ColorParser(s))
    .collect {
      case Right(color) => color
    }
    .runWith(Sink.seq)

1 Ответ

0 голосов
/ 10 января 2019

это пример изучения идентичного списка цветов:

case class Color(n: String, name: String, lightOrDark: String, n2: String)

val k1 = Color("1", "red", "light", "10")
val k2 = Color("1", "blue", "dark", "11")
val k3 = Color("1", "orange", "dark", "11")
val k4 = Color("1", "red", "light", "10")
val k5 = Color("1", "red", "dark", "200")

println(k1.hashCode() == k2.hashCode())
println(k1.hashCode() == k4.hashCode())

val set = mutable.Set.empty[Int]

val colorList = List(k1, k2, k3, k4, k5)

val restResult = 
Source
.fromIterator(colorList.iterator _)
  .map { color =>
    val hashCode = color.hashCode()
    val res = !set.contains(hashCode)
    set += hashCode
    res
  }.takeWhile(identity, inclusive = true)
  .runWith(Sink.last)


restResult.onComplete {
  case Success(value) =>
    println(value)
    system.terminate()

  case Failure(e) =>
    e.printStackTrace()
    system.terminate()
}

весь источник здесь

...