[英]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
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.