如何将一个自定义对象与该序列中的另一个自定义对象进行比较,创建两个序列?

问题描述 投票:0回答:1
case class Submission(name: String, plannedDate: Option[LocalDate], revisedDate: Option[LocalDate])

val submission_1 = Submission("Åwesh Care", Some(2020-05-11), Some(2020-06-11))
val submission_2 = Submission("robin Dore", Some(2020-05-11), Some(2020-05-30))
val submission_3 = Submission("AIMS Hospital", Some(2020-01-24), Some(2020-07-30))

val submissions = Seq(submission_1, submission_2, submission_3)

拆分 提交 这样,计划日期和修订日期相同的提交材料就会被转到以下地方: 同一日期组 和其他人去 剩余.

val (sameDateGroup, remainder) = someFunction(submissions)

示例结果如下。

sameDateGroup 本该

Seq(Submission("Åwesh Care", Some(2020-05-11), Some(2020-06-11)),
    Submission("robin Dore", Some(2020-05-11), Some(2020-05-30)))

剩余 应该有。

Seq(Submission("AIMS Hospital", Some(2020-01-24), Some(2020-07-30)))
scala user-defined-functions scala-collections
1个回答
2
投票

所以,如果我理解这里的逻辑,submission A 与提交日期相同 B (而且两者都会进入 sameDateGrooup)IFF。

   subA.plannedDate == subB.plannedDate
OR subA.plannedDate == subB.revisedDate
OR subA.revisedDate == subB.plannedDate
OR subA.revisedDate == subB.revisedDate

同样,反过来说,也是提交。C 属于 remainder IFF类别。

    subC.plannedDate // is unique among all planned dates
AND subC.plannedDate // does not exist among all revised dates
AND subC.revisedDate // is unique among all revised dates
AND subC.revisedDate // does not exist among all planned dates

我认为这就是你所描述的那样。

import java.time.LocalDate

case class Submission(name        : String
                     ,plannedDate : Option[LocalDate]
                     ,revisedDate : Option[LocalDate])

val submission_1 = Submission("Åwesh Care"
                             ,Some(LocalDate.parse("2020-05-11"))
                             ,Some(LocalDate.parse("2020-06-11")))
val submission_2 = Submission("robin Dore"
                             ,Some(LocalDate.parse("2020-05-11"))
                             ,Some(LocalDate.parse("2020-05-30")))
val submission_3 = Submission("AIMS Hospital"
                             ,Some(LocalDate.parse("2020-01-24"))
                             ,Some(LocalDate.parse("2020-07-30")))

val submissions = Seq(submission_1, submission_2, submission_3)

val pDates = submissions.groupBy(_.plannedDate)
val rDates = submissions.groupBy(_.revisedDate)
val (sameDateGroup, remainder) = submissions.partition(sub =>
          pDates(sub.plannedDate).lengthIs > 1 ||
          rDates(sub.revisedDate).lengthIs > 1 ||
          pDates.keySet(sub.revisedDate) ||
          rDates.keySet(sub.plannedDate))

1
投票

一个简单的方法是计算列表中每个提交的匹配提交的数量,然后用它来分割列表。

def matching(s1: Submission, s2: Submission) =
  s1.plannedDate == s2.plannedDate || s1.revisedDate == s2.revisedDate

val (sameDateGroup, remainder) =
  submissions.partition { s1 =>
    submissions.count(s2 => matching(s1, s2)) > 1
  }

列表中的 matching 函数可以包含任何需要的特定测试。

这就是 O(n^2) 所以对于很长的列表,需要更复杂的算法。


0
投票

我想这个就可以了。

很抱歉,有些变量名不是很有意义,因为我在尝试这个时用了不同的大小写类。出于某些原因,我只想到使用 .groupBy 后面的。所以我不太推荐使用这个,因为它有点不理解,用groupby可以更容易解决。

case class Submission(name: String, plannedDate: Option[String], revisedDate: Option[String])

val l = 
  List(
    Submission("Åwesh Care", Some("2020-05-11"), Some("2020-06-11")),
    Submission("robin Dore", Some("2020-05-11"), Some("2020-05-30")),
    Submission("AIMS Hospital", Some("2020-01-24"), Some("2020-07-30")))

val t = l
  .map((_, 1))
  .foldLeft(Map.empty[Option[String], (List[Submission], Int)])((acc, idnTuple) => idnTuple match {
    case (idn, count) => {
      acc
        .get(idn.plannedDate)
        .map { 
          case (mapIdn, mapCount) => acc + (idn.plannedDate -> (idn :: mapIdn, mapCount + count))
        }.getOrElse(acc + (idn.plannedDate -> (List(idn), count)))
    }})
  .values
  .partition(_._2 > 1)

val r = (t._1.map(_._1).flatten, t._2.map(_._1).flatten)

println(r)

基本上是按照map-reduce字数模式来做的。

如果有人看到这一点,知道如何更容易地进行元组解构,请在评论中告诉我。

© www.soinside.com 2019 - 2024. All rights reserved.