ruby-changes:63902
From: Marc-Andre <ko1@a...>
Date: Fri, 4 Dec 2020 19:44:59 +0900 (JST)
Subject: [ruby-changes:63902] 1804c3368c (master): [ruby/set] Add `Set#<=>`
https://git.ruby-lang.org/ruby.git/commit/?id=1804c3368c From 1804c3368cf4a94791fafa9701f79a2e6f76d5d8 Mon Sep 17 00:00:00 2001 From: Marc-Andre Lafortune <github@m...> Date: Thu, 1 Oct 2020 23:55:46 -0400 Subject: [ruby/set] Add `Set#<=>` https://github.com/ruby/set/commit/447974a374 diff --git a/lib/set.rb b/lib/set.rb index cb07037..625046d 100644 --- a/lib/set.rb +++ b/lib/set.rb @@ -45,9 +45,9 @@ https://github.com/ruby/ruby/blob/trunk/lib/set.rb#L45 # == Comparison # # The comparison operators <, >, <=, and >= are implemented as -# shorthand for the {proper_,}{subset?,superset?} methods. However, -# the <=> operator is intentionally left out because not every pair of -# sets is comparable ({x, y} vs. {x, z} for example). +# shorthand for the {proper_,}{subset?,superset?} methods. +# The <=> operator reflects this order, or return `nil` for +# sets that both have distinct elements ({x, y} vs. {x, z} for example). # # == Example # @@ -302,6 +302,19 @@ class Set https://github.com/ruby/ruby/blob/trunk/lib/set.rb#L302 end alias < proper_subset? + # Returns 0 if the set are equal, + # -1 / +1 if the set is a proper subset / superset of the given set, + # or nil if they both have unique elements. + def <=>(set) + return unless set.is_a?(Set) + + case size <=> set.size + when -1 then -1 if proper_subset?(set) + when +1 then +1 if proper_superset?(set) + else 0 if self.==(set) + end + end + # Returns true if the set and the given set have at least one # element in common. # diff --git a/test/test_set.rb b/test/test_set.rb index 54ef80b..05431e4 100644 --- a/test/test_set.rb +++ b/test/test_set.rb @@ -332,6 +332,24 @@ class TC_Set < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/test_set.rb#L332 } end + def test_spacecraft_operator + set = Set[1,2,3] + + assert_nil(set <=> 2) + + assert_nil(set <=> set.to_a) + + [Set, Set2].each { |klass| + assert_equal(-1, set <=> klass[1,2,3,4], klass.name) + assert_equal( 0, set <=> klass[3,2,1] , klass.name) + assert_equal(nil, set <=> klass[1,2,4] , klass.name) + assert_equal(+1, set <=> klass[2,3] , klass.name) + assert_equal(+1, set <=> klass[] , klass.name) + + assert_equal(0, Set[] <=> klass[], klass.name) + } + end + def assert_intersect(expected, set, other) case expected when true -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/