Thomas Lang
Thomas Lang

Reputation: 501

Ruby sort array with objects by first character of string

this is my first try using ruby, this is probably a simple problem, I have been stuck for an hour now, I have a ruby array with some objects in it, and I want that array to sort by the first character in the objects name property (which I make sure is always a number.)

the names are similar to:

4This is an option

3Another option

1Another one

0Another one

2Second option

I have tried:

objectArray.sort_by {|a| a.name[0].to_i}
objectArray.sort {|a,b| a.name[0].to_i <=> b.name.to_i}

In both cases my arrays sorting doesnt change.. (also used the destructive version of sort! and sort_by!)

I looped through the array like this:

objectArray.each do |test|
  puts test.name[0].to_i  
  puts "\n"
end

and sure enough I see the integer value it should have

Upvotes: 0

Views: 1880

Answers (2)

Eric Duminil
Eric Duminil

Reputation: 54253

Just sort by name. Since strings are sorted in lexicographic order, the objects will be sorted by name's first character :

class MyObject
  attr_reader :name
  def initialize(name)
    @name = name
  end

  def to_s
    "My Object : #{name}"
  end
end

names = ['4This is an option',
         '3Another option',
         '1Another one',
         '0Another one',
         '2Second option']

puts object_array = names.map { |name| MyObject.new(name) }
# My Object : 4This is an option
# My Object : 3Another option
# My Object : 1Another one
# My Object : 0Another one
# My Object : 2Second option

puts object_array.sort_by(&:name)
# My Object : 0Another one
# My Object : 1Another one
# My Object : 2Second option
# My Object : 3Another option
# My Object : 4This is an option

If you want, you could also define MyObject#<=> and get the correct sorting automatically :

class MyObject
  def <=>(other)
    name <=> other.name
  end
end

puts object_array.sort
# My Object : 0Another one
# My Object : 1Another one
# My Object : 2Second option
# My Object : 3Another option
# My Object : 4This is an option

Upvotes: 0

Vasili
Vasili

Reputation: 905

Tried with an array like this one:

[
  { id: 5, name: "4rge" }, 
  { id: 7, name: "3gerg" }, 
  { id: 0, name: "0rege"}, 
  { id: 2, name: "2regerg"}, 
  { id: 8, name: "1frege"}
]

And I don't have any issues with @sagarpandya82's answer:

arr.sort_by { |a| a[:name][0] }
# => [{:id=>0, :name=>"0rege"}, {:id=>8, :name=>"1frege"}, {:id=>2, :name=>"2regerg"}, {:id=>7, :name=>"3gerg"}, {:id=>5, :name=>"4rge"}] 

Upvotes: 1

Related Questions