[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

How to sort this hash?

x1

12/23/2005 11:26:00 PM

Is it possible to sort the jobs hash below based on values such as
command, start_time and stop_time?

Ideally, sort_by would be dynamically provided and I would output the
jobs entries based on the value defined for sort_by.



--------------------------(basic_script.rb)------------------------
sort_by = "start_time" #<---- I'd like to use something like this to
define which job is listed first

jobs = {
"2231" => {"command" => "test_a.bash",
"start_time" => "20051211",
"stop_time" => "20051222"},
"1131" => {"command" => "test_b.bash",
"start_time" => "20051011",
"stop_time" => "20051122"},
"231" => {"command" => "test_c.bash",
"start_time" => "20051215",
"stop_time" => "20051227"}
}

jobs.each do |job, attributes|
puts "------------------"
puts attributes["command"]
puts attributes["start_time"]
puts attributes["stop_time"]
end
--------------------------(/basic_script.rb)------------------------

This is the default output:
./basic_script.rb
------------------
test_c.bash
20051215
20051227
------------------
test_b.bash
20051011
20051122
------------------
test_a.bash
20051211
20051222


Id like to have the dynamics of say, ordering these by attribute such
as start_time:

(I wish I could get this)
test_b.bash
20051011
20051122
------------------
test_a.bash
20051211
20051222
------------------
test_c.bash
20051215
20051227


Any suggestions?

thanks in advance.


10 Answers

Florian Groß

12/23/2005 11:32:00 PM

0

Simon Kröger

12/24/2005 12:02:00 AM

0

x1 wrote:
> Is it possible to sort the jobs hash below based on values such as
> command, start_time and stop_time?
>
> Ideally, sort_by would be dynamically provided and I would output the
> jobs entries based on the value defined for sort_by.

This should do:

jobs.sort{|a,b|a[1][sort_by] <=> b[1][sort_by]}.each do |k, attributes|
puts "------------------"
puts attributes["command"]
puts attributes["start_time"]
puts attributes["stop_time"]
end

cheers

Simon


x1

12/24/2005 12:05:00 AM

0

Thank you for the reply.

I tried adding your suggestions but ended up with an error:
>ruby array_test.rb
array_test.rb:19:in `[]': cannot convert String into Integer (TypeError)
from array_test.rb:19
from array_test.rb:18:in `map'
from array_test.rb:18
from array_test.rb:17:in `sort_by'
from array_test.rb:17:in `each'
from array_test.rb:17:in `sort_by'
from array_test.rb:17
>Exit code: 1


The script is:

--------------------------------------

jobs = {
"2231" => {"command" => "test_a.bash",
"start_time" => "20051211",
"stop_time" => "20051222"},
"1131" => {"command" => "test_b.bash",
"start_time" => "20051011",
"stop_time" => "20051122"},
"231" => {"command" => "test_c.bash",
"start_time" => "20051215",
"stop_time" => "20051227"}
}

sort_keys = ["start_time", "stop_time"]
jobs.sort_by do |job|
sort_keys.map do |key|
job[key]
end
end

On 12/23/05, Florian Groß <florgro@gmail.com> wrote:
> x1 wrote:
>
> > Is it possible to sort the jobs hash below based on values such as
> > command, start_time and stop_time?
> >
> > Ideally, sort_by would be dynamically provided and I would output the
> > jobs entries based on the value defined for sort_by.
> >
> > sort_by = "start_time" #<---- I'd like to use something like this to
> > define which job is listed first
> >
> > jobs = {
> > "2231" => {"command" => "test_a.bash",
> > "start_time" => "20051211",
> > "stop_time" => "20051222"},
> > "1131" => {"command" => "test_b.bash",
> > "start_time" => "20051011",
> > "stop_time" => "20051122"},
> > "231" => {"command" => "test_c.bash",
> > "start_time" => "20051215",
> > "stop_time" => "20051227"}
> > }
>
> sort_keys = ["start_time", "stop_time"]
> jobs.sort_by do |job|
> sort_keys.map do |key|
> job[key]
> end
> end
>
> Note that this will only work as long as all sort_keys are present in
> every job.
>
> You might want to check the documentation for Enumerable#sort_by, but
> let me document the special thing in this case as well.
>
> sort_by's block can return multiple values as an Array. In that case it
> will first sort by the first value then by the second one and so on.
> This is used in the above sample where every job is sorted by the fields
> representing the sort_keys on that specific job.
>
> --
> http://flgr...
>
>
>


x1

12/24/2005 12:17:00 AM

0

Simon!! That worked :-D *huge grin*

If you don't mind me asking, have you had to use this before? I
wouldnt consider myself a top notch developer but between the ruby
docs and google searches, I would have never figured this out...

Any tips out how you did? Just.. development experience? Thanks again!!

On 12/23/05, x1 <caldridge@gmail.com> wrote:
> Thank you for the reply.
>
> I tried adding your suggestions but ended up with an error:
> >ruby array_test.rb
> array_test.rb:19:in `[]': cannot convert String into Integer (TypeError)
> from array_test.rb:19
> from array_test.rb:18:in `map'
> from array_test.rb:18
> from array_test.rb:17:in `sort_by'
> from array_test.rb:17:in `each'
> from array_test.rb:17:in `sort_by'
> from array_test.rb:17
> >Exit code: 1
>
>
> The script is:
>
> --------------------------------------
>
> jobs = {
> "2231" => {"command" => "test_a.bash",
> "start_time" => "20051211",
> "stop_time" => "20051222"},
> "1131" => {"command" => "test_b.bash",
> "start_time" => "20051011",
> "stop_time" => "20051122"},
> "231" => {"command" => "test_c.bash",
> "start_time" => "20051215",
> "stop_time" => "20051227"}
> }
>
> sort_keys = ["start_time", "stop_time"]
> jobs.sort_by do |job|
> sort_keys.map do |key|
> job[key]
> end
> end
>
> On 12/23/05, Florian Groß <florgro@gmail.com> wrote:
> > x1 wrote:
> >
> > > Is it possible to sort the jobs hash below based on values such as
> > > command, start_time and stop_time?
> > >
> > > Ideally, sort_by would be dynamically provided and I would output the
> > > jobs entries based on the value defined for sort_by.
> > >
> > > sort_by = "start_time" #<---- I'd like to use something like this to
> > > define which job is listed first
> > >
> > > jobs = {
> > > "2231" => {"command" => "test_a.bash",
> > > "start_time" => "20051211",
> > > "stop_time" => "20051222"},
> > > "1131" => {"command" => "test_b.bash",
> > > "start_time" => "20051011",
> > > "stop_time" => "20051122"},
> > > "231" => {"command" => "test_c.bash",
> > > "start_time" => "20051215",
> > > "stop_time" => "20051227"}
> > > }
> >
> > sort_keys = ["start_time", "stop_time"]
> > jobs.sort_by do |job|
> > sort_keys.map do |key|
> > job[key]
> > end
> > end
> >
> > Note that this will only work as long as all sort_keys are present in
> > every job.
> >
> > You might want to check the documentation for Enumerable#sort_by, but
> > let me document the special thing in this case as well.
> >
> > sort_by's block can return multiple values as an Array. In that case it
> > will first sort by the first value then by the second one and so on.
> > This is used in the above sample where every job is sorted by the fields
> > representing the sort_keys on that specific job.
> >
> > --
> > http://flgr...
> >
> >
> >
>


Jeff

12/24/2005 12:57:00 AM

0

Simon, would you be willing to explain the syntax you used here:

> jobs.sort{|a,b|a[1][sort_by] <=> b[1][sort_by]}.each do |k, attributes|


I just can't quite understand the [sort_by] usage here...?

Thanks (and apologies for the newbieness :-)

Jeff

--
Posted via http://www.ruby-....


Florian Groß

12/24/2005 1:05:00 AM

0

Florian Groß

12/24/2005 1:24:00 AM

0

Jeff

12/24/2005 1:46:00 AM

0

> So if sort_by is "command" it will sort the jobs by the value

Ah! I thought it was referring to something related to
Enumerable.sort_by.

Got it. Thanks.

--
Posted via http://www.ruby-....


Adam Akhtar

8/22/2008 2:30:00 AM

0



jobs.sort{|a,b|a[1][sort_by] <=> b[1][sort_by]}.each do |k, attributes|
puts "------------------"
puts attributes["command"]
puts attributes["start_time"]
puts attributes["stop_time"]
end


Im a newb but i wouldnt have thought a[1][sort_by] would have worked. I
tried accessing this hash in irb in the same way

a = {"job" = > {"wage" => 30, "time" => 60}}

a[1]["wage"] and got an error
NoMethodError: undefined method `[]' for nil:NilClass

why does it work???? Can you only access a hash like that within a sort
block?



--
Posted via http://www.ruby-....

Adam Akhtar

8/22/2008 2:40:00 AM

0

just found the answer to my question here

http://www.ruby-...topic/163...

for sort, ruby converts a hash to an array as hashes are not orderable
(is that a word??). Therefore accessing what seems to be a hash like an
array is in fact ok as it really is an array.

--
Posted via http://www.ruby-....