为什么 Scala 列表没有排序?

发布于 2024-10-08 04:54:20 字数 337 浏览 2 评论 0原文

Scala 中的列表没有隐式排序是否有原因?

val lists = List(List(2, 3, 1), List(2, 1, 3))
lists.sorted

error: could not find implicit value for parameter ord: Ordering[List[Int]]

编辑

是的,我的问题是为什么没有已经隐含在范围内的内置排序。对我来说,显然第二个列表应该“小于”第一个列表,因为 0 处的项目相等,而第二个列表的 1 处的项目较低。我想知道是否可能没有好的答案,当列表有两种不同的大小。

Is there a reason why there is no implicit Ordering for Lists in Scala?

val lists = List(List(2, 3, 1), List(2, 1, 3))
lists.sorted

error: could not find implicit value for parameter ord: Ordering[List[Int]]

EDIT

Yes, my question is why there is no built-in Ordering that's already implicitly in scope. To me, it seems obvious that the second list should be "less than" the first list since the items at 0 are equal and the second list has the lower item at 1. I was wondering if maybe it's that there's no good answer when the Lists are two different sizes.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

ぽ尐不点ル 2024-10-15 04:54:20

我认为这是一个疏忽。字典顺序对 Seq 确实有意义。我们应该将它添加到标准库中。

I think it's an oversight. Lexicographic ordering does make sense on Seqs. We should add it to the standard library.

把昨日还给我 2024-10-15 04:54:20

顺便说一句,即使在我修复此问题之前,您也可以通过其他方式执行此操作:

scala> List[Iterable[Int]](List(2, 3, 1), List(2, 1, 3)).sorted
res0: List[Iterable[Int]] = List(List(2, 1, 3), List(2, 3, 1))

scala> List(List(2, 3, 1), List(2, 1, 3)).sorted(Ordering[Iterable[Int]])
res1: List[List[Int]] = List(List(2, 1, 3), List(2, 3, 1))

但现在它的工作原理就像您希望的那样。

编辑:由于必要隐含的粗略分歧问题,我将其移出了默认范围。具有像这样跨越界限的隐式转换:

implicit def SeqDerived[CC[X] <: collection.Seq[X], T](implicit ord: Ordering[T]): Ordering[CC[T]]

...是潜在的问题根源。它将在 2.9 中可用,但您必须按如下方式导入它。

scala> val lists = List(List(2, 3, 1), List(2, 1, 3))
lists: List[List[Int]] = List(List(2, 3, 1), List(2, 1, 3))

scala> lists.sorted
<console>:9: error: could not find implicit value for parameter ord: Ordering[List[Int]]
       lists.sorted
             ^

scala> import Ordering.Implicits._
import Ordering.Implicits._

scala> lists.sorted
res1: List[List[Int]] = List(List(2, 1, 3), List(2, 3, 1))

Incidentally even before I fixed this you could do this other ways:

scala> List[Iterable[Int]](List(2, 3, 1), List(2, 1, 3)).sorted
res0: List[Iterable[Int]] = List(List(2, 1, 3), List(2, 3, 1))

scala> List(List(2, 3, 1), List(2, 1, 3)).sorted(Ordering[Iterable[Int]])
res1: List[List[Int]] = List(List(2, 1, 3), List(2, 3, 1))

But now it works like you'd hope.

Edit: due to sketchy divergence issues with the requisite implicit I moved it out of the default scope. Having an implicit conversion which acts across a bound like this:

implicit def SeqDerived[CC[X] <: collection.Seq[X], T](implicit ord: Ordering[T]): Ordering[CC[T]]

...is a potential recipe for issues. It'll be available in 2.9, but you have to import it as follows.

scala> val lists = List(List(2, 3, 1), List(2, 1, 3))
lists: List[List[Int]] = List(List(2, 3, 1), List(2, 1, 3))

scala> lists.sorted
<console>:9: error: could not find implicit value for parameter ord: Ordering[List[Int]]
       lists.sorted
             ^

scala> import Ordering.Implicits._
import Ordering.Implicits._

scala> lists.sorted
res1: List[List[Int]] = List(List(2, 1, 3), List(2, 3, 1))
千笙结 2024-10-15 04:54:20

您拥有的是列表的列表,而不是整数的列表。您缺少的是确定列表是否<=另一个列表的标准。

这就是错误消息的内容:我找不到将列表与另一个列表进行比较的方法,您应该明确提供一个。

如果您的问题是“为什么列表没有与其他列表的内置比较方法”,那么,事情就是这样。

What you have is a list of lists, not a list of integers. What you are missing is a criteria for determining whether a list is <= another list, or not.

That's what the error message says: I can't find a way to compare a list to another list, you should provide one explicitly.

If your question was "why don't list have a built-in comparison method against other lists", well, that's just the way it is.

傲鸠 2024-10-15 04:54:20

List[Int] 类上唯一真正合理的总顺序是字典顺序(即比较列表的第一个元素,如果它们相等则比较第二个元素,如果秒相等则比较第三个元素,等等)。标准库没有提供这一点,可能是因为实际需要它的情况并不多。创建从 List[X] 到 Ordering[List[X]] 的隐式转换来实现它是很容易的,然后您可以在需要的地方简单地导入该转换。

The only really sensible total order over the class of List[Int] would be lexicographic (i.e, compare the first elements of the list, then the second if they are equal, the third if the seconds are equal, etc.). This isn't provided by the standard library, probably because there aren't that many cases where it's actually needed. It would be easy enough to create an implicit conversion from List[X] to Ordering[List[X]] that would implement that, and then you could simply import that conversion wherever you needed it.

星軌x 2024-10-15 04:54:20

您可以使用 sortWith。这不会考虑不同大小的列表,因为 zip 会消除差异,但我认为它的作用类似于您所追求的:

lists.sortWith((a,b) => {
  a.zip(b).filterNot(x => x._1 == x._2) match {
    case Nil => true
    case t => t._1 < t._2
  }
})

You can use sortWith. This doesn't take differently sized lists into account because zip will throw out the difference, but I think it does something like what you're after:

lists.sortWith((a,b) => {
  a.zip(b).filterNot(x => x._1 == x._2) match {
    case Nil => true
    case t => t._1 < t._2
  }
})
亣腦蒛氧 2024-10-15 04:54:20

Scala 2.13.3 - 调用 sorted 方法对我有用:

import scala.math.Ordering.Implicits.seqOrdering
val lists = List(List(2, 3, 1), List(2, 1, 3))
print(lists.sorted)   // prints List(List(2, 1, 3), List(2, 3, 1)) 

sorted 方法是 StrictOptimizedSeqOps 特征的成员,:

override def sorted[B >: A](implicit ord: Ordering[B]): C

Scala 2.13.3 - invoking sorted method worked for me:

import scala.math.Ordering.Implicits.seqOrdering
val lists = List(List(2, 3, 1), List(2, 1, 3))
print(lists.sorted)   // prints List(List(2, 1, 3), List(2, 3, 1)) 

sorted method is a member of StrictOptimizedSeqOps trait,:

override def sorted[B >: A](implicit ord: Ordering[B]): C
奈何桥上唱咆哮 2024-10-15 04:54:20

在较新的 Scala 版本中(使用 2.12.5 进行测试)有一个 对 Iterable[A] 进行排序。只需将正确的类型赋予变量 lists

scala> val lists = List(List(2, 3, 1), List(2, 1, 3))
lists: List[List[Int]] = List(List(2, 3, 1), List(2, 1, 3))

scala> (lists: List[Iterable[Int]]).sorted
res0: List[Iterable[Int]] = List(List(2, 1, 3), List(2, 3, 1))

或者将元素转换为 Iterable[] 的实例(这对于 List[] 实例来说是无操作的) ):

scala> lists.map(_.toIterable).sorted
res1: List[Iterable[Int]] = List(List(2, 1, 3), List(2, 3, 1))

In newer Scala versions (tested with 2.12.5) there's an Ordering for Iterable[A]. Just ascribe the right type to your variable lists:

scala> val lists = List(List(2, 3, 1), List(2, 1, 3))
lists: List[List[Int]] = List(List(2, 3, 1), List(2, 1, 3))

scala> (lists: List[Iterable[Int]]).sorted
res0: List[Iterable[Int]] = List(List(2, 1, 3), List(2, 3, 1))

Or convert the elements to instances of Iterable[] (which is a no-op for instances of List[]):

scala> lists.map(_.toIterable).sorted
res1: List[Iterable[Int]] = List(List(2, 1, 3), List(2, 3, 1))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文