You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Scala如何查找List匹配项 计算水果匹配得分返回对应人员

Scala 实现水果匹配得分映射

注意:Scala标准不可变Map不支持重复键,你给出的示例中两个得分同为2的条目直接写入Map[Int, Person]时,后写入的Sarah会覆盖Simon的条目造成数据丢失,因此推荐使用Map[Int, List[Person]]结构按得分聚合人员,以下为具体实现。

核心逻辑

  • 提前将客人携带的水果名称提取为集合,降低匹配查询的时间复杂度
  • 对每位就餐人员,统计其携带水果中与客人水果重合的数量作为得分
  • 按得分对人员做分组聚合,得到最终的得分-人员映射

完整实现代码

// 基础数据结构定义
case class Fruit(fruit: String)
case class Person(str: String, value: List[Fruit])

object LunchSeatMatcher {
  def main(args: Array[String]): Unit = {
    // 初始化已知数据
    val guest: Person = Person("Unknown", List(Fruit("Apple"), Fruit("Pear"), Fruit("Grapes")))
    val seatOwners = List(
      Person("Bob", List(Fruit("Apple"), Fruit("Pear"), Fruit("Grapes"))),
      Person("Peter", List(Fruit("Apple"), Fruit("Pineapple"), Fruit("Mango"))),
      Person("Simon", List(Fruit("Apple"), Fruit("Pear"), Fruit("Mango"))),
      Person("sarah", List(Fruit("Pear"), Fruit("Grapes"), Fruit("Mango")))
    )

    // 提取客人的水果集合用于匹配
    val guestFruits = guest.value.map(_.fruit).toSet

    // 单个人的得分计算逻辑:统计匹配的水果种类数
    def calcMatchScore(person: Person): Int = 
      person.value.map(_.fruit).count(guestFruits.contains)

    // 推荐写法:按得分分组,同得分人员存入列表,无数据丢失
    val scoreToPeople: Map[Int, List[Person]] = seatOwners.groupBy(calcMatchScore)
    /* 输出结果:
    Map(
      3 -> List(Person("Bob", List(Fruit("Apple"), Fruit("Pear"), Fruit("Grapes")))),
      2 -> List(Person("Simon", List(Fruit("Apple"), Fruit("Pear"), Fruit("Mango"))), Person("sarah", List(Fruit("Pear"), Fruit("Grapes"), Fruit("Mango")))),
      1 -> List(Person("Peter", List(Fruit("Apple"), Fruit("Pineapple"), Fruit("Mango"))))
    )
    */

    // 若严格按你给出的单Person映射结构写,会出现同得分覆盖问题
    val scoreToSinglePerson: Map[Int, Person] = seatOwners.map(p => calcMatchScore(p) -> p).toMap
    /* 输出结果中2分仅保留最后一个sarah:
    Map(
      3 -> Person("Bob", ...),
      2 -> Person("sarah", ...),
      1 -> Person("Peter", ...)
    )
    */
  }
}

补充说明

  • 当前实现按水果种类匹配计数,不考虑水果重复个数,和你给出的示例得分完全一致:Bob得3分、Simon和Sarah得2分、Peter得1分。
  • 如果需要按水果个数计数(例如客人带2个苹果、对方带1个苹果仅算1次匹配,带2个算2次),可以将水果集合替换为频次Map,再做累加计数即可。
  • 如果你确实需要支持一键多值的Map结构且不想用List聚合,可以使用可变的scala.collection.mutable.MultiMap,但日常开发更推荐不可变的分组结果,无副作用、线程安全。

内容的提问来源于stack exchange,提问作者Ry2254

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 02:27:27