Ask a Question related to Ruby, Design and Development.
-
Osuka #1
Sorting a Hash
I'm Having some trouble sorting a hash!, the hash contents are like
this:
1 is Ayumi Hamasaki
2 is Zone
1 is Two-Mix
2 is Shazna
1 is L'arc~en~ciel
Problem is: I want to ordered it in a descending order but using
Hash.invert I lose data 'cos there can't be several keys that are the
same, so any ideas of how to do this
this is the code the comments are there 'cos they del some data
---------------CODE------------------------
jdir="E:/emusic/jrock"
Dir.chdir(jdir)
jlist=Array.new
jlist=Dir.entries(jdir)
jlist.sort!
$serie=Array.new
$jcount=Hash.new()
jlist.each do |entry|
$serie=entry.sub(/ - +[a-zA-Z0-9\-.!=&+~\(\) ']*/,'')
if($jcount.has_key?($serie))
$jcount[$serie]=$jcount[$serie]+1
else
$jcount.store($serie,1)
end
end
#$jcount=$jcount.invert
#$jcount=$jcount.sort
#$jcount.reverse!
$jcount.each {|key, value| print value, " is ", key, "\n" }
---------------CODE------------------------
comments on the regexp are also welcomed
"artist - name(~=live'now-now'~[what])-.mp3" to "artist"
Osuka Guest
-
Sorting Hash of Hashes with HEAP module
Hi, I would like to use the Heap module from CPAN to sort Hash of Hashes by values, keeping track of what pairs of keys belong to what values. ... -
hash sorting
On 12/15/2003 3:17 AM, B. Rothstein wrote: Check the Perl FAQ. -
avoid repitive code while sorting hash arrays
suppose I have a hash like %users =( 'cvs' => { 'uname' => 'cvs', 'uid' => 582, 'gid' => 500 }, 'radvd' => { 'uname' => 'radvd', -
Sorting Hash of teams for premier league table
This is what the hash looks like (with only 4 teams in it) ignore the Competition: { 'Team' => , 'Competition' => } ] } -
sorting on hash contents
Hi, all. Say I have a hash of 4 elements, val and name h = "1,2,3,fred" h = "4,1,2,jack" h = "3,3,4,jill" How do I define: -
Osuka #2
Re: Sorting a Hash
Brian Candler <B.Candler@pobox.com> wrote in message news:<20030701112013.A20127@linnet.org>...
Sorry about that!! but you got the right idea!!> On Tue, Jul 01, 2003 at 07:07:55PM +0900, Osuka wrote:>> > I'm Having some trouble sorting a hash!, the hash contents are like
> > this:
> >
> > 1 is Ayumi Hamasaki
> > 2 is Zone
> > 1 is Two-Mix
> > 2 is Shazna
> > 1 is L'arc~en~ciel
> I don't understand. Firstly, do you mean that your hash is like this:
>
> myhash = {
> 'Ayumi Hamasaki' => 1,
> 'Zone' => 2,
> 'Two-Mix' => 1,
> 'Shazna' => 2,
> 'L\'Arc~en~ciel' => 1,
> }
>
Arrg I did tried this and the to_a approach but i forgot something way> Secondly, how do you want to sort it? If you just do
>
> myhash.sort
>
> then you will get it sorted alphabetically by the key, i.e.
>
> => [["Ayumi Hamasaki", 1], ["L'Arc~en~ciel", 1], ["Shazna", 2],
> ["Two-Mix", 1], ["Zone", 2]]
>
> If you want to sort it by the numeric value, then you can pass in an
> explicit block which shows how to compare the values:
>
> myhash.sort {|x,y| x[1] <=> y[1]}
>
> => [["Ayumi Hamasaki", 1], ["L'Arc~en~ciel", 1], ["Two-Mix", 1],
> ["Shazna", 2], ["Zone", 2]]
>
> (you can see all the 1's come before the 2's)
too simple! if myhash.sort {|x,y| x[1] <=> y[1]} does return the
sorted array but doesn't actually affects the given array so I have to
assign the returned value to the hash I'm using, how come I miss it!!!
all the problem was here!!
Yes I want it sorted by descending values not alphabetical
[["Shazna", 2],["Zone", 2],["Ayumi Hamasaki", 1], ["L'Arc~en~ciel",
1], ["Two-Mix", 1]]
yes values become keys and keys values, that's why it was "working">
> Essentially the thing to remember is: when you sort a hash, it first gets
> converted to an array, where each element is a two-element array of
> [key,value] pairs.
>
> You can do this conversion yourself explicitly:
>
> myhash.to_a
>>> > Problem is: I want to ordered it in a descending order but using
> > Hash.invert I lose data 'cos there can't be several keys that are the
> > same, so any ideas of how to do this
> By descending order of what?
>
> Hash.invert doesn't reverse the order of elements, it swaps the keys and the
> values!! If you want a reverse alphabetical sort, try:
>
> myhash.sort.reverse
>
> => [["Zone", 2], ["Two-Mix", 1], ["Shazna", 2], ["L'Arc~en~ciel", 1],
> ["Ayumi Hamasaki", 1]]
>
but eliminating some new keys ie duplicated ones. doing a reverse then
converting to an array meaned that I could easily get it sorted as I
wanted but I would lose elements because of key duplicates, which its
my fault for not considering that a lot of the values are identical.well thanks!! now it works and sorry for a not so clear post.> Regards,
>
> Brian.
Osuka Guest
-
Brian Candler #3
Re: Sorting a Hash
On Wed, Jul 02, 2003 at 01:50:30AM +0900, Osuka wrote:
Of course, the result of the sort is an array, not a hash. There's no point>> > If you want to sort it by the numeric value, then you can pass in an
> > explicit block which shows how to compare the values:
> >
> > myhash.sort {|x,y| x[1] <=> y[1]}
> >
> > => [["Ayumi Hamasaki", 1], ["L'Arc~en~ciel", 1], ["Two-Mix", 1],
> > ["Shazna", 2], ["Zone", 2]]
> >
> > (you can see all the 1's come before the 2's)
> Arrg I did tried this and the to_a approach but i forgot something way
> too simple! if myhash.sort {|x,y| x[1] <=> y[1]} does return the
> sorted array but doesn't actually affects the given array so I have to
> assign the returned value to the hash I'm using, how come I miss it!!!
> all the problem was here!!
trying to put the elements back into a hash, because a hash is _unordered_
by definition. Effectively they would end up in a random order again.
Ah OK. Actually quite a nice solution is:> Yes I want it sorted by descending values not alphabetical
> [["Shazna", 2],["Zone", 2],["Ayumi Hamasaki", 1], ["L'Arc~en~ciel",
> 1], ["Two-Mix", 1]]
myhash.sort { |x,y| y[1] <=> x[1] }
or even better,
myhash.sort { |x,y| y.reverse <=> x.reverse }
The 'reverse' swaps x[0]/x[1], so it sorts by the number before sorting by
the name. Using y...<=>...x gives a sort in reverse order. So this will
group together all the entries by number, sorted in reverse numeric order,
and within groups it will sort by reverse alphabetic order.
If you want reverse numeric and forward alphabetic, you can get a bit more
imaginative with the contents of the comparison function:
myhash.sort { |x,y|
cmp = y[1] <=> x[1]
if cmp != 0
cmp
else
x[0] <=> y[0]
end
}
=> [["Shazna", 2], ["Zone", 2], ["Ayumi Hamasaki", 1], ["L'Arc~en~ciel", 1],
["Two-Mix", 1]]
Cheers,
Brian.
Brian Candler Guest
-
Osuka #4
Re: Sorting a Hash
Brian Candler <B.Candler@pobox.com> wrote in message news:<20030701211409.GA66745@uk.tiscali.com>...
Yes I mistyped there!! I tried to mean the array returned, 'cos the> On Wed, Jul 02, 2003 at 01:50:30AM +0900, Osuka wrote:>> >> > > If you want to sort it by the numeric value, then you can pass in an
> > > explicit block which shows how to compare the values:
> > >
> > > myhash.sort {|x,y| x[1] <=> y[1]}
> > >
> > > => [["Ayumi Hamasaki", 1], ["L'Arc~en~ciel", 1], ["Two-Mix", 1],
> > > ["Shazna", 2], ["Zone", 2]]
> > >
> > > (you can see all the 1's come before the 2's)
> > Arrg I did tried this and the to_a approach but i forgot something way
> > too simple! if myhash.sort {|x,y| x[1] <=> y[1]} does return the
> > sorted array but doesn't actually affects the given array so I have to
> > assign the returned value to the hash I'm using, how come I miss it!!!
> > all the problem was here!!
> Of course, the result of the sort is an array, not a hash. There's no point
> trying to put the elements back into a hash, because a hash is _unordered_
> by definition. Effectively they would end up in a random order again.
>>> > Yes I want it sorted by descending values not alphabetical
> > [["Shazna", 2],["Zone", 2],["Ayumi Hamasaki", 1], ["L'Arc~en~ciel",
> > 1], ["Two-Mix", 1]]
> Ah OK. Actually quite a nice solution is:
>
> myhash.sort { |x,y| y[1] <=> x[1] }
>
> or even better,
>
> myhash.sort { |x,y| y.reverse <=> x.reverse }
>
> The 'reverse' swaps x[0]/x[1], so it sorts by the number before sorting by
> the name. Using y...<=>...x gives a sort in reverse order. So this will
> group together all the entries by number, sorted in reverse numeric order,
> and within groups it will sort by reverse alphabetic order.
>
> If you want reverse numeric and forward alphabetic, you can get a bit more
> imaginative with the contents of the comparison function:
>
> myhash.sort { |x,y|
> cmp = y[1] <=> x[1]
> if cmp != 0
> cmp
> else
> x[0] <=> y[0]
> end
> }
>
> => [["Shazna", 2], ["Zone", 2], ["Ayumi Hamasaki", 1], ["L'Arc~en~ciel", 1],
> ["Two-Mix", 1]]
>
> Cheers,
>
> Brian.
hash its no more after a sort, I should be more careful with those
words. And thanks a lot Brian I didn't thought of doing an
alphabetical(as secondary rule) sort after the numerical, I guess that
was coming even in the example that I gave on what I wanted I did it
like that.Now it all works and as a little exercise I turned it into a
class(a bit of overkill but...gotta learn)
Osuka Guest
-
Brian Candler #5
Re: Sorting a Hash
On Thu, Jul 03, 2003 at 08:24:37AM +0900, Osuka wrote:
I don't think it's overkill at all. In Ruby it often makes sense to make a> Now it all works and as a little exercise I turned it into a
> class(a bit of overkill but...gotta learn)
class even for simple cases.
Your code will probably be clearer because the class will have its own <=>
compare method, so you can sort those objects in their preferred order
without having to write that magic compare block each time.
Cheers,
Brian.
Brian Candler Guest



Reply With Quote

