in reply to Sorting an array of hashes and filenames

The general reason you are having problems is that you are trying to sort both the hashes and the filenames, as if they were equivalent items. They aren't: They are related.

This calls for a Perl hash, which keeps related things together.

I've been trying to adapt one into your code for five minutes or so, and have come to the conclusion that either I don't understand line 3, or there is something completely screwy with your code snippit.

Therefore, pseudo-code to do what you want:

my %file_hashes; foreach my $file ( #List_of_files ) { my $hash = hash_fuc($file); $file_hashes{$hash} = $file; } foreach my $hash ( sort keys %file_hashes ) { print "$hash $file_hashes{$hash}\n"; }

You'll probably want to read up on hashes in Perl. They are useful.

(Edit: Removed brainfart at the end.)

Replies are listed 'Best First'.
Re^2: Sorting an array of hashes and filenames
by Anonymous Monk on Jan 14, 2009 at 16:00 UTC
    (By the way: You could make the key the filename, depending on what else you were doing in the code. Just use 'values' instead of 'keys' above.)

    Not really. You can get the value from the key, but not the other way around. To sort by value you need something like this:
    foreach my $hash ( sort {$file_hashes{$a} cmp $file_hashes{$b}} keys %file_hashes ) { print "$hash $file_hashes{$hash}\n"; }

      Good point. I must have twisted my brain by the time I got around to writing that.

Re^2: Sorting an array of hashes and filenames
by learningperl01 (Beadle) on Jan 14, 2009 at 20:31 UTC
    Thanks for all the replies. Here is the code that I have but still prints out the hashes unsorted? Not sure why?
    foreach my $file ( $fns ) { open(FH, $file) or die "Can't open '$file': $!"; binmode(FH); my $hash = Digest::MD5->new->addfile(*FH)->hexdigest; $file_hashes{$hash} = $file; } foreach my $hash ( sort {$file_hashes{$a} cmp $file_hashes{$b} +} keys %file_hashes ) { print "$hash $file_hashes{$hash}\n"; } } ------------Results--------------- 32e3d09e0c2ff94316410b1444fbbb37a file1.txt 123d087078b62487c1d4c02f4c943af09 file2.txt 3ddbadc770e1c25a91aa186d3b0595945 file3.txt a3ff6417e3b703604c400965330ea6612 file4.txt b78c8fafdb9a5d4df6b36dcd35c56f6aa file5.txt

      That sorted it perfectly: Exactly as you told it to.

      By the hash values, not the keys. The values of the hash (as you've constructed it) are the filenames, and if you'll notice, those are precisely in order.

      Take out the {$file_hashes{$a} cmp $file_hashes{$b}}. It isn't what you want. (If you really want to put something there, put in {$a cmp $b}, but that's the default...

        actually I was trying to sort on the first column only (the hash values) not the file names. How do I just sort on the first column, but still print the hash and the file name but sorted based on the hashes. thanks for all the help once again