Forum: Ruby on Rails ordering after a inject

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Steve O. (Guest)
on 2006-05-03 20:59
(Received via mailing list)
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
Gregory S. (Guest)
on 2006-05-03 20:59
(Received via mailing list)
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
Steve O. (Guest)
on 2006-05-03 20:59
(Received via mailing list)
Aww. Thanks.
Jean-François (Guest)
on 2006-05-03 21:05
(Received via mailing list)
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.
Steve O. (Guest)
on 2006-05-03 21:05
(Received via mailing list)
Thanks for this, Jean-Francois. This is helpful. I'll check it out.

Steve
This topic is locked and can not be replied to.