Array#sort -block with conditions for <=>'ing

Discussion in 'Ruby' started by carp __, Mar 8, 2007.

  1. carp __

    carp __ Guest

    Hello Rubyists,

    I want to sort an array of objects of the same class (MyClass). The
    array should be sorted by arbitrary attributes of that class, but the
    problem is that one attribute can be nil.

    The code looks like this:

    my_array.sort {
    |x,y| x.some_attribute <=> y.some_attribute
    }

    Naturally, if some_attribute is nil, the comparison failed (since nil is
    not comparable). I am looking for something like this:

    my_array.sort {
    |x,y| x.some_attribute <=> y.some_attribute unless
    (x.some_attribute.nil? or y.some_attribute.nil?)
    }

    which I have tried without having success (Error was: comparison of
    MyClass with MyClass failed).

    Does anyone know how to do it? Thanks in advance!

    --
    Posted via http://www.ruby-forum.com/.
    carp __, Mar 8, 2007
    #1
    1. Advertising

  2. On 08/03/07, carp __ <> wrote:
    > Hello Rubyists,
    >
    > I want to sort an array of objects of the same class (MyClass). The
    > array should be sorted by arbitrary attributes of that class, but the
    > problem is that one attribute can be nil.
    >
    > The code looks like this:
    >
    > my_array.sort {
    > |x,y| x.some_attribute <=> y.some_attribute
    > }
    >
    > Naturally, if some_attribute is nil, the comparison failed (since nil is
    > not comparable). I am looking for something like this:
    >
    > my_array.sort {
    > |x,y| x.some_attribute <=> y.some_attribute unless
    > (x.some_attribute.nil? or y.some_attribute.nil?)
    > }
    >
    > which I have tried without having success (Error was: comparison of
    > MyClass with MyClass failed).
    >
    > Does anyone know how to do it? Thanks in advance!


    Define <=> on your class:

    class MyClass
    def <=>(other)
    if @some_attribute.nil?
    return -1
    elsif @other.some_attribute.nil?
    return 1
    else
    @some_attribute <=> other.some_attribute
    end
    end
    end

    Farrel
    Farrel Lifson, Mar 8, 2007
    #2
    1. Advertising

  3. On Thu, Mar 08, 2007 at 10:42:44PM +0900, carp __ wrote:
    > The code looks like this:
    >
    > my_array.sort {
    > |x,y| x.some_attribute <=> y.some_attribute
    > }
    >
    > Naturally, if some_attribute is nil, the comparison failed (since nil is
    > not comparable). I am looking for something like this:
    >
    > my_array.sort {
    > |x,y| x.some_attribute <=> y.some_attribute unless
    > (x.some_attribute.nil? or y.some_attribute.nil?)
    > }
    >
    > which I have tried without having success (Error was: comparison of
    > MyClass with MyClass failed).


    You have to return something from the comparison. Try something like:

    my_array.sort { |x,y|
    x1 = x.some_attribute
    y1 = y.some_attribute
    if (not x1.nil?) and (not y1.nil?)
    x1 <=> y1
    elsif x1.nil? and y1.nil?
    0
    elsif x1.nil?
    -1
    else
    1
    end
    }
    Brian Candler, Mar 8, 2007
    #3
  4. carp __

    carp __ Guest

    carp __, Mar 8, 2007
    #4
  5. carp __

    Phrogz Guest

    On Mar 8, 5:52 am, "Farrel Lifson" <> wrote:
    > Define <=> on your class:
    >
    > class MyClass
    > def <=>(other)
    > if @some_attribute.nil?
    > return -1
    > elsif @other.some_attribute.nil?
    > return 1
    > else
    > @some_attribute <=> other.some_attribute
    > end
    > end
    > end


    I find your style of mixing imperative and functional return
    parameters odd. I would have expected either:

    if foo
    -1
    elsif bar
    1
    else
    x <=> y
    end

    OR

    if foo
    return -1
    elsif bar
    return 1
    else
    return x <=> y
    end

    but not the combination you have above. FWIW, I favor the former
    style, as it's just a hair faster.
    Phrogz, Mar 9, 2007
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. morrell
    Replies:
    1
    Views:
    933
    roy axenov
    Oct 10, 2006
  2. rkk
    Replies:
    9
    Views:
    801
    CBFalconer
    Sep 24, 2006
  3. Navin
    Replies:
    1
    Views:
    668
    Ken Schaefer
    Sep 9, 2003
  4. GIMME
    Replies:
    5
    Views:
    177
    Thomas 'PointedEars' Lahn
    Jul 26, 2004
  5. Domenico Discepola

    multi-field array sort using Sort::Fields method

    Domenico Discepola, Apr 27, 2004, in forum: Perl Misc
    Replies:
    6
    Views:
    290
    Uri Guttman
    Apr 28, 2004
Loading...

Share This Page