简体   繁体   English

什么时候Scala中的一套比另一套少?

[英]When is one Set less than another in Scala?

I wanted to compare the cardinality of two sets in Scala. 我想比较Scala中两个集合的基数。 Since stuff sometimes "just work" in Scala, I tried using < between the sets. 由于在Scala中某些东西有时“可以正常工作”,因此我尝试在两个集合之间使用< It seems to go through, but I can't make any sense out of the result. 这似乎是可行的,但我对结果没有任何意义。

Example: 例:

scala> Set(1,2,3) < Set(1,4)
res20: Boolean = true
  • What does it return? 它返回什么?
  • Where can I read about this method in the API? 我在哪里可以了解API中的此方法?
  • Why isn't it listed anywhere under scala.collection.immutable.Set ? 为什么它不在scala.collection.immutable.Set下的任何位置列出?

Update: Even the order (??) of the elements in the sets seem to matter: 更新:甚至集合中元素的顺序 (??)也很重要:

scala> Set(2,3,1) < Set(1,3)
res24: Boolean = false

scala> Set(1,2,3) < Set(1,3)
res25: Boolean = true

This doesn't work with 2.8. 这不适用于2.8。 On Scala 2.7, what happens is this: 在Scala 2.7上,将发生以下情况:

scala.Predef.iterable2ordered(Set(1, 2, 3): Iterable[Int]) < (Set(1, 3, 2): Iterable[Int])

In other words, there's an implicit conversion defined on scala.Predef , which is "imported" for all Scala code, from an Iterable[A] to an Ordered[Iterable[A]] , provided there's an implicit A => Ordered[A] available. 换句话说,在scala.Predef定义了一个隐式转换,它对于所有Scala代码都是“导入”的,从Iterable[A]Ordered[Iterable[A]] ,前提是存在一个隐式A => Ordered[A]可用。

Given that the order of an iterable for sets is undefined, you can't really predict much about it. 鉴于集合的可迭代顺序是不确定的,因此您实际上无法对其进行太多预测。 If you add elements to make the set size bigger than four, for instance, you'll get entirely different results. 例如,如果添加元素以使设置大小大于4,则会得到完全不同的结果。

If you want to compare the cardinality, just do so directly: 如果要比较基数,请直接进行以下操作:

scala> Set(1, 2, 3).size < Set(2, 3, 4, 5).size
res0: Boolean = true

My knowledge of Scala is not extensive, but doing some test, I get the following: 我对Scala的了解并不广泛,但是通过一些测试,我得到了以下信息:

scala> Set(1,2) <
<console>:5: error: missing arguments for method < in trait Ordered;
follow this method with `_' if you want to treat it as a partially applied function
   Set(1,2) <
            ^

That tells me that < comes from the trait Ordered . 这告诉我<来自Ordered的特征。 More hints: 更多提示:

scala> Set(1,2) < _
res4: (Iterable[Int]) => Boolean = <function>

That is, the Set is evaluated into an Iterable , because maybe there is some implicit conversion from Iterable[A] to Ordered[Iterable[A]], but I'm not sure anymore... Tests are not consistent. 也就是说,将Set评估为一个Iterable ,因为可能存在从Iterable [A]到Ordered [Iterable [A]]的隐式转换,但我不确定...测试不一致。 For example, these two might suggest a kind of lexicographical compare: 例如,这两个可能建议一种字典上的比较:

scala> Set(1,2,3) < Set(1,2,4)
res5: Boolean = true

1 is equal, 2 is equal, 3 is less than 4. 1等于2等于3小于4

scala> Set(1,2,4) < Set(1,2,3)
res6: Boolean = false

But these ones don't: 但是这些都不是:

scala> Set(2,1) < Set(2,4)
res11: Boolean = true

scala> Set(2,1) < Set(2,2)
res12: Boolean = false

I think the correct answer is that found in the Ordered trait proper: There is no implementation for < between sets more than comparing their hashCode: 我认为正确的答案是在Ordered特性中找到的正确答案:集之间没有<实现,只能比较它们的hashCode:

It is important that the hashCode method for an instance of Ordered[A] be consistent with the compare method. 对于Ordered [A]实例的hashCode方法,必须与compare方法保持一致。 However, it is not possible to provide a sensible default implementation. 但是,不可能提供明智的默认实现。 Therefore, if you need to be able compute the hash of an instance of Ordered[A] you must provide it yourself either when inheiriting or instantiating. 因此,如果您需要能够计算Ordered [A]实例的哈希,则必须在初始化或实例化时自行提供哈希。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM