Project

General

Profile

Actions

Feature #21157

closed

Comparison operator <>

Feature #21157: Comparison operator <>

Added by lpogic (Łukasz Pomietło) 8 months ago. Updated 8 months ago.

Status:
Feedback
Assignee:
-
Target version:
-
[ruby-core:121172]

Description

I propose introducing a comparison operator <> which would give the following results:

1 <> 2 # => -1
2 <> 1 # => 1
1 <> 1 # => false
1 <> "a" # => true

With the help of the new operator, complex ordering expressions could be written explicitly. For example:

Point = Struct.new(:x, :y)
array = [Point.new(1, 2), Point.new(6, 4), Point.new(2, 2), Point.new(5, 2)]

array.sort{|a, b| a.y <> b.y || b.x <> a.x || 0 } # => [#<struct Point x=5, y=2>, #<struct Point x=2, y=2>, #<struct Point x=1, y=2>, #<struct Point x=6, y=4>]

The <> notation may look familiar to sql users, where it means 'not equal'. Defined in the form given it will retain this meaning to some extent:

a = b = 1
a_not_equal_b if a <> b
a_equal_b unless a <> b

Updated by Hanmac (Hans Mackowiak) 8 months ago Actions #1 [ruby-core:121173]

Isn't it easier to use sort_by instead? And then use an Array as Sorting Field?

array.sort_by {|o| [o.y, -o.x] } #=> [#<struct Point x=5, y=2>, #<struct Point x=2, y=2>, #<struct Point x=1, y=2>, #<struct Point x=6, y=4>]

Updated by lpogic (Łukasz Pomietło) 8 months ago Actions #2 [ruby-core:121174]

I think that not having to create intermediate arrays and referencing the x coordinate when y is different would be an advantage.

Updated by P3t3rU5 (Pedro Miranda) 8 months ago Actions #3 [ruby-core:121175]

comparison operator already exists it's <=>

if you want a class to be comparable you just include the Comparable module and implement <=>

Updated by nobu (Nobuyoshi Nakada) 8 months ago Actions #4 [ruby-core:121177]

  • Description updated (diff)

lpogic (Łukasz Pomietło) wrote:

I propose introducing a comparison operator <> which would give the following results:

1 <> 2 # => -1
2 <> 1 # => 1
1 <> 1 # => false
1 <> "a" # => true

I'm not sure what the last example means, maybe incomparable -> true?

With the help of the new operator, complex ordering expressions could be written explicitly. For example:

Point = Struct.new(:x, :y)
array = [Point.new(1, 2), Point.new(6, 4), Point.new(2, 2), Point.new(5, 2)]

array.sort{|a, b| a.y <> b.y || b.x <> a.x || 0 } # => [#<struct Point x=5, y=2>, #<struct Point x=2, y=2>, #<struct Point x=1, y=2>, #<struct Point x=6, y=4>]
array.sort{|a, b| (a.y <=> b.y).nonzero? || b.x <> a.x}

I agree that it would be a bit shorter/simpler, but I doubt it's worth adding new syntax.

The <> notation may look familiar to sql users, where it means 'not equal'.

Or BASIC users?
Anyway, <> in SQL is a boolean operator and not expected returing ±1.

Updated by lpogic (Łukasz Pomietło) 8 months ago Actions #5 [ruby-core:121178]

P3t3rU5 (Pedro Miranda) wrote in #note-3:

comparison operator already exists it's <=>

if you want a class to be comparable you just include the Comparable module and implement <=>

<=> is good enough for comparing a single property, e.g. a.y <=> b.y. Things get complicated when we want to compare several consecutive properties, e.g.:

array.sort do |a, b|
  result = a.y <=> b.y
  result == 0 ? b.x <=> a.x : result
end

Including the Comparable module simply moves this code to a different location. And this is only an option if we want to sort in natural order.

Updated by lpogic (Łukasz Pomietło) 8 months ago Actions #6 [ruby-core:121180]

nobu (Nobuyoshi Nakada) wrote in #note-4:

I'm not sure what the last example means, maybe incomparable -> true?

Yes, this is a case where objects are incomparable. I'm not sure if true is the most appropriate value, but I don't have a better idea at the moment.

nobu (Nobuyoshi Nakada) wrote in #note-4:

array.sort{|a, b| (a.y <=> b.y).nonzero? || b.x <=> a.x}

This actually solves the presented problem in a relatively clear way. Until now I was not aware of the existence of nonzero?.

nobu (Nobuyoshi Nakada) wrote in #note-4:

Or BASIC users?
Anyway, <> in SQL is a boolean operator and not expected returing ±1.

Sure. I only see the similarity when <> is used in logical expressions.

Updated by Eregon (Benoit Daloze) 8 months ago Actions #8 [ruby-core:121233]

Let's not add new syntax and methods for something which can easily be done with nonzero? (and which is BTW the main purpose of nonzero?)

Updated by nobu (Nobuyoshi Nakada) 8 months ago Actions #9 [ruby-core:121243]

  • Status changed from Open to Feedback

Added a reference to Numeric#nonzero? at d31c15d81f368614f81e8c32295d0529b66e7334.
Isn't it enough?

Updated by lpogic (Łukasz Pomietło) 8 months ago · Edited Actions #10 [ruby-core:121244]

Such a note in the documentation would certainly be advisable. Could a similar one be added to the max, min and minmax methods?

Actions

Also available in: PDF Atom