Ordering after a inject

Hi,

My results are getting out of order after I do the following command:

count = result.inject({}) { |hsh, row| hsh[row[‘name’]] =
row[‘count’].to_i;
hsh }

Why?

Here are more specifics:

My complete method is this (based off of acts_as_taggable code - not’
DHHs,
but the original one):

def self.sql_to_count_plays(lookback)
sql = [“SELECT t.name as name, COUNT(*) as count
FROM histories h, tags t
WHERE h.tag_id = t.id
AND created_on > ?
GROUP BY tag_id
ORDER BY name”, lookback]
result = find_by_sql(sql)
count = result.inject({}) { |hsh, row| hsh[row[‘name’]] =
row[‘count’].to_i; hsh }
count
end

The “result” is in the proper alpha order:
=> [#<Tag:0x3606ab0 @attributes={“name”=>“baseball”, “count”=>“2”}>,
#<Tag:0x360
6a68 @attributes={“name”=>“name”, “count”=>“29”}>, #<Tag:0x3606900
@attributes={
“name”=>“new”, “count”=>“3”}>, #<Tag:0x36065b8 @attributes={“name”=>“new
test fo
r tags”, “count”=>“4”}>, #<Tag:0x3606210 @attributes={“name”=>“serial”,
“count”=

“4”}>, #<Tag:0x3605fd0 @attributes={“name”=>“test”, “count”=>“1”}>]

but once it is processed through the result.inject function it gets out
of
alpha order:
=> {“new”=>3, “name”=>29, “new test for tags”=>4, “serial”=>4,
“test”=>1, "
baseball"=>2}

I can’t figure out why or how to correct it. I don’t have the latest
pickaxe
book which documents the inject function and can’t find much
documentation
on it on the web. I could turn it into an sorted array using “count =
count.sort_by { |r| r.name }”, but I don’t want it in an array. In need
it
in a hash.

Any ideas?

Kind regards,

Steve O.
http://www.smarkets.net

On Tue, May 02, 2006 at 10:12:11AM -0500, Steve O. wrote:
} My results are getting out of order after I do the following command:
}
} count = result.inject({}) { |hsh, row| hsh[row[‘name’]] =
row[‘count’].to_i;
} hsh }
}
} Why?
[…]
} but once it is processed through the result.inject function it gets
out of
} alpha order:
} => {“new”=>3, “name”=>29, “new test for tags”=>4, “serial”=>4,
“test”=>1, "
} baseball"=>2}
}
} I can’t figure out why or how to correct it. I don’t have the latest
pickaxe
} book which documents the inject function and can’t find much
documentation
} on it on the web. I could turn it into an sorted array using “count =
} count.sort_by { |r| r.name }”, but I don’t want it in an array. In
need it
} in a hash.

Hashes are unordered containers. They do not maintain order. That is not
what they do.

} Any ideas?
} Kind regards,
} Steve O.
–Greg

Aww. Thanks.

Hello Steve,

  • not’ DHHs, but the original one):

but once it is processed through the result.inject function it gets out of
alpha order:
=> {“new”=>3, “name”=>29, “new test for tags”=>4, “serial”=>4, “test”=>1, "
baseball"=>2}

I can’t figure out why or how to correct it. I don’t have the latest pickaxe
book which documents the inject function and can’t find much documentation
on it on the web. I could turn it into an sorted array using “count =
count.sort_by { |r| r.name }”, but I don’t want it in an array. In need it
in a hash.

Gregory has answered you but here some additional information :

1/ if you have my_hash = MyModel.sql_to_count_plays(lookback)

you can convert into a “sort of ordered hash like object”, in fact an
array of nested pairs, with Hash#sort method :

irb(main):001:0> my_hash={“new”=>3, “name”=>29, “new test for
tags”=>4, “serial”=>4, “test”=>1, “baseball”=>2}.sort
=> [[“baseball”, 2], [“name”, 29], [“new”, 3], [“new test for tags”,
4], [“serial”, 4], [“test”, 1]]

then you can iterate on each pair :

my_hash.each { |p| puts “#{p.first}(#{p.last})” }
baseball(2)
name(29)
new(3)
new test for tags(4)
serial(4)
test(1)

2/ There is an OrderedHash class in Rails.
In 1.0, it was class OrderedOptions, then it has been refactored a
little
bit OrderedOptions < OrderedHash in 1.1.
In trunk, it’s called (very recently) ActiveSupport::OrderedHash.

If you look in : activesupport/lib/active_support/ordered_options.rb
you will see that’s basically a “nested pairs in array” structure
encapsulated in an OrderedHash instance.

HTH,

-- Jean-François.

Thanks for this, Jean-Francois. This is helpful. I’ll check it out.

Steve