0Pricing
Scala for Backend Engineering & Functional Programming · 课时

分组与排序

groupBy 与 sortBy

分组与排序 是 CoddyKit 上的免费 Scala for Backend Engineering & Functional Programming 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Scala for Backend Engineering & Functional Programming 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。

组织数据

现实世界的数据通常需要根据某个属性进行分组,或根据某个键进行排序。Scala 集合提供了 groupBy、sortBy、sortWith 等操作,以声明式方式完成这些任务。

object Main {
  def main(args: Array[String]): Unit = {
    val nums = List(5, 3, 8, 1, 9, 2)
    println(nums.sorted)
  }
}

sorted:自然顺序

sorted 按元素的自然顺序排序(数字按升序排列,字符串按字母顺序排列)。它需要一个排序规则,而常见类型通常都提供了相应规则。

object Main {
  def main(args: Array[String]): Unit = {
    println(List(3, 1, 2).sorted)
    println(List("pear", "apple", "fig").sorted)
  }
}

sortBy:按键排序

sortBy 根据从每个元素中派生出的值进行排序。请提供一个用于提取排序键的函数。

object Main {
  def main(args: Array[String]): Unit = {
    val words = List("banana", "fig", "apple")
    val byLength = words.sortBy(_.length)
    println(byLength)
  }
}

按降序排序

要按降序排序,可以对数值键取负值,或使用 sorted(Ordering.Int.reverse)。对于派生键,使用带减号的 sortBy 更为简洁。

object Main {
  def main(args: Array[String]): Unit = {
    val nums = List(5, 3, 8, 1)
    println(nums.sortBy(-_))
    println(nums.sorted(Ordering.Int.reverse))
  }
}

sortWith:自定义比较器

sortWith 接收一个函数:当第一个参数应排在第二个参数之前时返回 true,从而让您完全控制排序顺序。

object Main {
  def main(args: Array[String]): Unit = {
    val nums = List(5, 3, 8, 1)
    val descending = nums.sortWith((a, b) => a > b)
    println(descending)
  }
}

按多个键排序

sortBy 可以返回一个元组,从而同时根据多个键排序:它先比较第一个元素,再用第二个元素打破平局。

object Main {
  def main(args: Array[String]): Unit = {
    val people = List(("Ann", 30), ("Bob", 25), ("Ann", 22))
    val sorted = people.sortBy { case (name, age) => (name, age) }
    println(sorted)
  }
}

groupBy:分区到 Map 中

groupBy 返回一个 Map:每个键都是您的函数返回的结果,每个值则是共享该键的元素列表。

object Main {
  def main(args: Array[String]): Unit = {
    val nums = List(1, 2, 3, 4, 5, 6)
    val byParity = nums.groupBy(_ % 2 == 0)
    println(byParity)
  }
}

按计算出的键分组

分组键可以是任何内容:首字母、长度或类别。每个不同的键都会成为一个分组。

object Main {
  def main(args: Array[String]): Unit = {
    val words = List("apple", "avocado", "banana", "cherry", "cranberry")
    val byFirstLetter = words.groupBy(_.head)
    byFirstLetter.foreach { case (letter, ws) => println(s"$letter -> $ws") }
  }
}

转换分组

分组后,您通常需要概括每个分组。可以使用 view.mapValues(或 map)转换各组的值,例如统计每组的元素数量。

object Main {
  def main(args: Array[String]): Unit = {
    val words = List("cat", "car", "dog", "deer", "cow")
    val counts = words.groupBy(_.head).view.mapValues(_.size).toMap
    println(counts)
  }
}

一步完成 groupMapReduce

groupMapReduce 会在一次遍历中完成分组、映射每个元素以及归约每组的值。这是一种简洁的方式,可用于构建每个类别的总和等汇总结果。

object Main {
  def main(args: Array[String]): Unit = {
    val sales = List(("books", 10), ("toys", 5), ("books", 7), ("toys", 3))
    val totals = sales.groupMapReduce(_._1)(_._2)(_ + _)
    println(totals)
  }
}

结合分组与排序

一种常见模式是:先将数据分组,再概括每组,最后对汇总结果排序。这里我们统计每个首字母对应的单词数量,并按数量排序。

object Main {
  def main(args: Array[String]): Unit = {
    val words = List("apple", "avocado", "banana", "cherry", "cranberry", "apricot")
    val ranked = words
      .groupBy(_.head)
      .view.mapValues(_.size).toList
      .sortBy(-_._2)
    println(ranked)
  }
}

快速检查

List(1,2,3,4).groupBy(_ % 2 == 0) 会返回什么?

回顾

您学习了分组和排序:

  • sorted — 自然顺序
  • sortBy — 按派生键排序(使用元组实现多键排序)
  • sortWith — 自定义比较器
  • groupBy — 分区到包含各个分组的 Map 中
  • groupMapReduce — 在一次遍历中完成分组、映射和归约

常见问题解答

「分组与排序」课时是免费的吗?

是的 — 「分组与排序」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Scala for Backend Engineering & Functional Programming 课程的其余内容,请升级到 CoddyKit PRO。 Scala for Backend Engineering & Functional Programming 课程共包含 4 节课。

「分组与排序」这节课中我会学到什么?

groupBy 与 sortBy 你通过在浏览器中直接运行的动手代码来练习 Scala for Backend Engineering & Functional Programming,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Scala for Backend Engineering & Functional Programming 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Scala for Backend Engineering & Functional Programming 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。

「分组与排序」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Scala for Backend Engineering & Functional Programming 课中编写并运行代码吗?

能。每节 Scala for Backend Engineering & Functional Programming 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. List、Vector、Set、Map
  2. 转换
  3. 折叠与归约
  4. 分组与排序
← 返回 Scala for Backend Engineering & Functional Programming