Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sorting an array of objects in Ruby by object attribute?

People also ask

How do you sort an array of objects in Ruby?

You can use the sort method on an array, hash, or another Enumerable object & you'll get the default sorting behavior (sort based on <=> operator) You can use sort with a block, and two block arguments, to define how one object is different than another (block should return 1, 0, or -1)

Can we sort array of objects?

To sort an array of objects, you use the sort() method and provide a comparison function that determines the order of objects.

Can you sort elements in a Ruby hash object?

Sorting Hashes in RubyTo sort a hash in Ruby without using custom algorithms, we will use two sorting methods: the sort and sort_by. Using the built-in methods, we can sort the values in a hash by various parameters.

How do you sort an array of elements?

rsort() - sort arrays in descending order. asort() - sort associative arrays in ascending order, according to the value. ksort() - sort associative arrays in ascending order, according to the key. arsort() - sort associative arrays in descending order, according to the value.


I recommend using sort_by instead:

objects.sort_by {|obj| obj.attribute}

Especially if attribute may be calculated.

Or a more concise approach:

objects.sort_by(&:attribute)

Yes, using Array#sort! this is easy.

myarray.sort! { |a, b|  a.attribute <=> b.attribute }

Ascending order :

objects_array.sort! { |a, b|  a.attribute <=> b.attribute }

or

objects_array.sort_by{ |obj| obj.attribute }

Descending order :

objects_array.sort! { |a, b|  b.attribute <=> a.attribute }

or

objects_array.sort_by{ |obj| obj.attribute }.reverse

in case you need sorting by two attributes, where first one is more important then second (means taking in account second arguments only if first arguments are equal), then you may do like this

myarray.sort{ |a,b| (a.attr1 == b.attr1) ? a.attr2 <=> b.attr2 : a.attr1 <=> b.attr1 }

or in case of array of arrays

myarray.sort{ |a,b| (a[0] == b[0]) ? a[1] <=> b[1] : a[0] <=> b[0] }

You can make any class sortable by overriding the <=> method:

class Person

  attr_accessor :first_name, :last_name

  def initialize(first_name, last_name)
    @first_name = first_name
    @last_name = last_name
  end

  def <=>(other)
    @last_name + @first_name <=> other.last_name + other.first_name
  end

end

Now an array of Person objects will be sortable on last_name.

ar = [Person.new("Eric", "Cunningham"), Person.new("Homer", "Allen")]

puts ar  # => [ "Eric Cunningham", "Homer Allen"]  (Person objects!)

ar.sort!

puts ar  # => [ "Homer Allen", "Eric Cunningham" ]