Sort an array based on an attribute of its objects

Hi all

The title of this topic is not very good, but I didn’t really know how
to describe it in just a few words…

So here is what I need to do:

I have a array of some objects:

[obj1, obj2, obj3, obj4]

All objects have a method “status” that returns a status object, like
“open”, “request”, “cancelled”, “completed” etc.

Now I’d like to sort the elements after theses statuses into a new hash,
so in the end it should look something like this:

{status1 => [obj1, obj3],
status3 => [obj2],
status4 => [obj4]}

I need this because I want then to iterate through the hash and display
an HTML list grouped by status:

  • Request:
    • Object 1
    • Object 3
  • Cancelled:
    • Object 2
  • ... and so on...

What’s an elegant way to do this? :slight_smile:

Thanks a lot,
Josh

Hi –

On Thu, 28 Aug 2008, Joshua M. wrote:

I need this because I want then to iterate through the hash and display

  • Cancelled:
    • Object 2
  • ... and so on...

    What’s an elegant way to do this? :slight_smile:

    In Ruby 1.9 you can do:

    array.group_by {|obj| obj.status }

    and get a hash. If you need to roll your own:

    class Array
    def group_by
    hash = Hash.new {|h,k| h[k] = [] }
    each {|e| hash[yield(e)] << e }
    hash
    end
    end

    (or in a module, or whatever).

    David

    On Thu, Aug 28, 2008 at 1:58 PM, David A. Black [email protected]
    wrote:
    David beat me to the line, but as somebody will post an inject based
    solution anyway, why not let it be me ;).

    class Array
    def group_by message = nil
    inject( Hash.new {|h,k| h[k] = [] } ){ |h, e|
    h[message ? e.send( message ) : yield(e)] << e
    h
    }
    end
    end

    p %w{ Hello Brave GNU World }.group_by {|o| o.size }
    p %w{ Hello Brave GNU World }.group_by( :size )

    Cheers
    Robert


    http://ruby-smalltalk.blogspot.com/

    There’s no one thing that’s true. It’s all true.

    On Thu, Aug 28, 2008 at 1:39 PM, Joshua M. [email protected] wrote:

    {status1 => [obj1, obj3],
    status3 => [obj2],
    status4 => [obj4]}

    If working with a Set is fine (there’s #to_set) that’s provided by
    Set#classify.