Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Return top-N of Hashes - hash splice?

Reply
Thread Tools

Return top-N of Hashes - hash splice?

 
 
Edward Wijaya
Guest
Posts: n/a
 
      10-02-2004
Hi

With this hashes:

$hash = {
'1-1' => 3,
'2-3' => 2,
'2-2' => 1,
'1-2' => 6,
'1-3' => 3
};

What's the best to retrieve the top-N hashes
from it. So, with N = 3 it will become:

$hash_top3 = {
'1-1' => 3,
'2-3' => 2,
'2-2' => 1,
};

Thanks beforehand.

Regards,
Edward WIJAYA
SINGAPORE


--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
 
Reply With Quote
 
 
 
 
Tad McClellan
Guest
Posts: n/a
 
      10-02-2004
Edward Wijaya <(E-Mail Removed)> wrote:

> With this hashes:
>
> $hash = {
> '1-1' => 3,
> '2-3' => 2,
> '2-2' => 1,
> '1-2' => 6,
> '1-3' => 3
> };
>
> What's the best to retrieve the top-N hashes



Hashes do not have a "top". They are UNordered.

If you need to preserve the order, then you have chosen
the wrong data structure.


What is it that you are actually trying to accomplish?


--
Tad McClellan SGML consulting
http://www.velocityreviews.com/forums/(E-Mail Removed) Perl programming
Fort Worth, Texas
 
Reply With Quote
 
 
 
 
Jürgen Exner
Guest
Posts: n/a
 
      10-02-2004
Edward Wijaya wrote:
> With this hashes:
>
> $hash = {
> '1-1' => 3,
> '2-3' => 2,
> '2-2' => 1,
> '1-2' => 6,
> '1-3' => 3
> };
>
> What's the best to retrieve the top-N hashes
> from it. So, with N = 3 it will become:


Hashes by definition don't have a (usable) sequence or order. Therefore your
request for the top n elements of a hash doesn't make any sense.

If you want/need to preserve the sequence of elements then you picked the
wrong data structure.
Use an array instead. And to get the first $n elements use an array slice
@foo = @bar[0..$n-1];

jue


 
Reply With Quote
 
Edward Wijaya
Guest
Posts: n/a
 
      10-02-2004
On Sat, 02 Oct 2004 04:14:53 GMT, Jürgen Exner <(E-Mail Removed)>
wrote:

Hi,
Thanks so much for the reply:

> Hashes by definition don't have a (usable) sequence or order. Therefore
> your request for the top n elements of a hash doesn't make any sense.


Sorry for not being clear before.
I should have sorted the hash according to it's value
and then pick top-N from it.

> Use an array instead.

It's difficult for me to change the current
data-structure of my code, as it's inherently designed
for hash.

Moreover, I found about Tie::IxHash module.
Which is suppose to "impose" order in the hash.
However since I am new in using Method through external
module, there are 2 issues I fail to deal with.
Your valuable suggestion is important to me.

Here is my code:

__BEGIN__
use strict;
use warnings;
use Tie::IxHash;

my $N = 2;
my %hash = {
#1) Must sort by value,then 2) Select Top N after sorting it.
'1-1' => 3,
'2-3' => 2,
'2-2' => 1,
'1-2' => 6,
'1-3' => 3
};

my $t = Tie::IxHash->new(%hash);
$t->SortByValue; #sorting it, is this correct?
my @topN = $t->Splice(0, $N); #splicing it

__END__

My problem is:
1. Is the way I invoke the Sorted new hash is correct?,
How can I view it? I tried: print "%$hash\n"; # doesn't seem to work
2. The "spliced" array is in the form of array,
Is there any efficient way/method to recover it into Hash?

Thanks and hope to hear from you again,

Regards
Edward WIJAYA
SINGAPORE
 
Reply With Quote
 
Edward Wijaya
Guest
Posts: n/a
 
      10-02-2004


Sorry.
Slight correction, the hash should come with bracket:

my %hash =(
#1) Must sort by value,then 2) Select Top N after sorting it.
'1-1' => 3,
'2-3' => 2,
'2-2' => 1,
'1-2' => 6,
'1-3' => 3
);


Regards,
Edward WIJAYA
SINGAPORE
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      10-02-2004
Edward Wijaya wrote:
> On Sat, 02 Oct 2004 04:14:53 GMT, Jürgen Exner <(E-Mail Removed)>
> wrote:
>> Hashes by definition don't have a (usable) sequence or order.
>> Therefore your request for the top n elements of a hash doesn't make
>> any sense.

>
> Sorry for not being clear before.
> I should have sorted the hash according to it's value
> and then pick top-N from it.


Again, a hash does not have a (usable) sequence, therefore the very notion
of sorting a hash doesn't make sense.

You may sort a list of the keys of the hash (sort keys %myhash) or a list of
the values of the hash (sort values %myhash), but you cannot sort a hash.

>> Use an array instead.

> It's difficult for me to change the current
> data-structure of my code, as it's inherently designed
> for hash.
>
> Moreover, I found about Tie::IxHash module.


Sorry, never used that one.

jue


 
Reply With Quote
 
John W. Krahn
Guest
Posts: n/a
 
      10-02-2004
Jürgen Exner wrote:
> Edward Wijaya wrote:
>>
>>Sorry for not being clear before.
>>I should have sorted the hash according to it's value
>>and then pick top-N from it.

>
> Again, a hash does not have a (usable) sequence, therefore the very notion
> of sorting a hash doesn't make sense.
>
> You may sort a list of the keys of the hash (sort keys %myhash) or a list of
> the values of the hash (sort values %myhash), but you cannot sort a hash.


Sure you can. A hash returns a list like any other list.

$ perl -le' %x = qw/ a b c d x y /; print for %x; print; print for sort %x'
c
d
a
b
x
y

a
b
c
d
x
y



John
--
use Perl;
program
fulfillment
 
Reply With Quote
 
Joe Smith
Guest
Posts: n/a
 
      10-02-2004
Edward Wijaya wrote:

> On Sat, 02 Oct 2004 04:14:53 GMT, Jürgen Exner <(E-Mail Removed)>
> wrote:
>> Hashes by definition don't have a (usable) sequence or order.
>> Therefore your request for the top n elements of a hash doesn't make
>> any sense.

>
> Sorry for not being clear before.
> I should have sorted the hash according to it's value
> and then pick top-N from it.


You cannot sort a hash. Period.

You can sort the hash keys into a list and then use that list to
access the corresponding values in order by key, but the hash
itself remains unsorted.

@sorted_keys = sort keys %hash;
print "$_ -> $hash{$_}\n" for @sorted_keys;
print "keys: @sorted_keys\n";
print "values: @hash{@sorted_keys}\n";

Or you can create an array of keys sorted such that the corresponding
values are in order.

$N = $number_of_items_to_extract;
@keys_sorted_by_value = sort { $hash{$a} cmp $hash{$b} } keys %hash;
@top_N_keys = splice @keys_sorted_by_value,-$N;
print "The keys @top_N_keys have values @hash{@top_N_keys}\n";
print "The remaining values are @hash{@keys_sorted_by_value}\n";

>> Use an array instead.

>
> It's difficult for me to change the current
> data-structure of my code, as it's inherently designed
> for hash.


In that case, use a hash and an array, as shown above.
-Joe
 
Reply With Quote
 
Shawn Corey
Guest
Posts: n/a
 
      10-02-2004
John W. Krahn wrote:
> Sure you can. A hash returns a list like any other list.
>
> $ perl -le' %x = qw/ a b c d x y /; print for %x; print; print for sort %x'


No, these convert the hash to an array, then sorts it.

--- Shawn
 
Reply With Quote
 
Jürgen Exner
Guest
Posts: n/a
 
      10-02-2004
John W. Krahn wrote:
> Jürgen Exner wrote:
>> Edward Wijaya wrote:
>>>
>>> Sorry for not being clear before.
>>> I should have sorted the hash according to it's value
>>> and then pick top-N from it.

>>
>> Again, a hash does not have a (usable) sequence, therefore the very
>> notion of sorting a hash doesn't make sense.
>>
>> You may sort a list of the keys of the hash (sort keys %myhash) or a
>> list of the values of the hash (sort values %myhash), but you cannot
>> sort a hash.

>
> Sure you can. A hash returns a list like any other list.
>
> $ perl -le' %x = qw/ a b c d x y /; print for %x; print; print for
> sort %x' c


Ok, I never thought of it that way!
Good that I set my coffee down before reading your post, otherwise I would
have to clean my keyboard now....

This is really a good one, should keep it in mind for the next person asking
how to sort a hash.

jue


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
hash of hash of hash of hash in c++ rp C++ 1 11-10-2011 04:45 PM
"Pseudo-hashes are deprecated" error and accessing a hash of hashes ernestm@mindspring.com Perl Misc 3 01-31-2006 04:40 AM
Hash of hashes, of hashes, of arrays of hashes Tim O'Donovan Perl Misc 5 10-28-2005 05:59 AM
Hashes of hashes or just one hash ? Perl Learner Perl Misc 11 06-09-2005 06:55 AM
Performance Improvement of complex data structure (hash of hashes of hashes) Scott Gilpin Perl Misc 2 08-26-2004 01:02 AM



Advertisments