From: Ammar Ali Date: 2010-11-13T01:18:32+09:00 Subject: Re: help sorting objects by their instance field On Fri, Nov 12, 2010 at 5:43 PM, Aaron Haas wrote: > I'm trying to figure out how to sort objects in an array by one of their > instance > variables, in this case last name. The person class has a first name, > last name, and an address object. The address book class is made up of > an array of persons. How do I sort the array of persons in > alphabetically by the persons last name instance fields. I added a > getLastname method to the persons class, but I'm not sure on the logic. > > [CODE] > class Person >    attr_accessor :fname, :lname, :address > >    # initializer >    def initialize >        @fname = @lname = "" >        # since address is an object >        @address = Address.new >    end > >    # assign given values to Person object >    def crPerson (aFname, aLname, aAddress) >        @fname = aFname >        @lname = aLname >        @address = aAddress >    end To answer your main question first: @persons.sort_by {|person| person.aLname} Some notes: Do you need to create blank Person objects? If not, you do the initialization work of crPerson inside the initialize method. def initialize(first_name, last_name, address) @fname = aFname @lname = aLname @address = aAddress end >    def get_lname >        return @lname >    end If you use the attr_reader, attr_writer, and attr_accessor keywords, you can do away with getter/setter methods. Example class Person attr_accessor :first_name, :last_name end Now you can just write: p = Person.new('Joe', 'Schmoe', '123 Main Street') p.last_name # gets last name p.first_name # gets first name THe same applies for setting values: p.last_name = 'Bloe' >    # class variable. keeps track of number of address book entries >    @@instances = 0 You can accomplish this with: @persons.length Class variables in ruby are rarely used, or what one thinks they need. >     #  totally lost on this part >    # print sorted by last name method using person's get_lname method >    def print_addresses >      @persons.each { |p| persons[p].get_lname.sort  } First the sort is being applied to the last name. I doubt that's what you want. Also, you don't need to index into the persons array here, the p is the person you want already. This is the same: @persons.each { |p| persons.last_name  } I already addressed the sorting at the top of the post. >      end # close while loop >      # print sorted array >      @persons.each { |p| yield p } >    end This doesn't print the persons, it just yields them. This does: @persons.each {|p| puts p} If you meant to use yield, then the printing is done in a block passed to AddressBook class print_addresses method, so you need to add a block argument and yield to it. def print_addresses(&block) @persons.sort_by { |p| persons.last_name } @persons.each { |p| yield p } end Then you use it like: address_book.print_addresses {|p| puts p} Note that I have used the common ruby naming convention for variables and methos, last_name, instead of aLastName. HTH, Ammar