I’ve an array of hashes I want to sort, first by key1 and then subsort by
key2. I’ve some code that works but was wondering if there is a more
idiomatic method of doing this in Ruby:
create an array of Hashes. We want to sort by firstKey, then secondKey.
unsorted = []
100.times do |t|
unsorted.push({ “firstKey” => rand(10), “secondKey” => t})
end
I’ve an array of hashes I want to sort, first by key1 and then subsort by
key2. I’ve some code that works but was wondering if there is a more
idiomatic method of doing this in Ruby:
create an array of Hashes. We want to sort by firstKey, then secondKey.
unsorted =
100.times do |t|
unsorted.push({ “firstKey” => rand(10), “secondKey” => t})
end
a shorter one (not tested)
#create a hash of firstKey containing array of k2
top={}
unsorted.each{|k1, k2|
if top[k1]
top[k1] << k2
else
top[k1] = [k2]
end
}
sorted =
top.sort.each{|k1, ak2|
ak2.sort.each {|k2|
sorted << [k1, k2]
}
}
p sorted
I’ve an array of hashes I want to sort, first by key1 and then subsort by
key2. I’ve some code that works but was wondering if there is a more
idiomatic method of doing this in Ruby:
One way would be:
unsorted = (0…100).map {|t| { :k1 => rand(10), :k2 => t} }
sorted = unsorted.sort do |a,b|
if (n = a[:k1] <=> b[:k1]).zero?
a[:k2] <=> b[:k2]
else
n
end
end
or, if you don’t have my probably ridiculous aversion to the ternary
operator:
unsorted = (0…100).map {|t| { :k1 => rand(10), :k2 => t} }
sorted = unsorted.sort do |a,b|
(n = a[:k1] <=> b[:k1]).zero? ? a[:k2] <=> b[:k2] : n
end
The h.id in the first case is necessary to prevent the individual
hashes from being compared, which doesn’t work. In either case, we punt
by relying on the fact that <=> on arrays implements lexicographic
ordering.
I’ve an array of hashes I want to sort, first by key1 and then subsort by
key2. I’ve some code that works but was wondering if there is a more
idiomatic method of doing this in Ruby:
create an array of Hashes. We want to sort by firstKey, then secondKey.
unsorted =
100.times do |t|
unsorted.push({ “firstKey” => rand(10), “secondKey” => t})
end
This works in 1.6 too. But if you have Ruby 1.7 and don’t need to
be compatible to 1.6 I’d use Enumerable#sort_by, as others have
shown. Maybe the 1.6 code is a bit more efficient, but I haven’t
tested this.