Sorting with multiple keys
Mandrake
created: 2006-02-03 02:08:11
Good day Monks, Here's my problem.
I have a text file with content

name=Document1.doc type=Word author=aAuthor 
name=Document1.doc type=Excel author=bAuthor
name=Document1.doc type=Text author=cAuthor
name=Document1.doc type=Excel author=dAuthor
name=Document1.doc type=Word author=eAuthor
My problem is to sort this file and write to another (first based on the key "type" and then on the key "author") so that the output file looks like :
name=Document1.doc type=Excel author=bAuthor
name=Document1.doc type=Excel author=dAuthor
name=Document1.doc type=Text author=cAuthor
name=Document1.doc type=Word author=aAuthor 
name=Document1.doc type=Word author=eAuthor
What I have tried is to write a function which accepts one key name and sort the file based on that key. Again the function will be invoked with the second key. But when I invoked the function with second key, the output happened to be sorted in second key alone(the first level sorting has gone which is obvious). Is there any way with which I can do this in one stretch.?
Any suggestions welcome.
#$field is the position of the element (sort key) in the #line
   open INPUT , $input || die $input.$! ;

    while () {
        @fields = split(" ",$_) ;
        push @{$hash{$fields[$field]}}, $_ ;
        $hash_keys{$fields[$field]} = $fields[$field] unless exists $hash_keys{$fields[1]} ;
    }
    for $element (sort keys %hash_keys) {
        open OUTPUT, ">>$output" || $output.$! ;
        print OUTPUT @{$hash{$element}} ;
        close OUTPUT ;
    }
    close INPUT ;
Many thanks for your time..
Re: Sorting with multiple keys
created: 2006-02-03 02:23:27

Here's a starting point:

use strict;
use warnings;

my @rows;

push @rows, [split ' '] while ;

print "@$_\n" for sort {$a->[1] cmp $b->[1] or $a->[2] cmp $b->[2]} @rows;

__DATA__
name=Document1.doc type=Word author=aAuthor
name=Document1.doc type=Excel author=bAuthor
name=Document1.doc type=Text author=cAuthor
name=Document1.doc type=Excel author=dAuthor
name=Document1.doc type=Word author=eAuthor

Prints:

name=Document1.doc type=Excel author=bAuthor
name=Document1.doc type=Excel author=dAuthor
name=Document1.doc type=Text author=cAuthor
name=Document1.doc type=Word author=aAuthor
name=Document1.doc type=Word author=eAuthor

DWIM is Perl's answer to Gödel
Re: Sorting with multiple keys
created: 2006-02-03 02:34:51

[0] Perl> @toSort = split "\n", <<'END';
name=Document1.doc type=Word author=aAuthor
name=Document1.doc type=Excel author=bAuthor
name=Document1.doc type=Text author=cAuthor
name=Document1.doc type=Excel author=dAuthor
name=Document1.doc type=Word author=eAuthor
END
;;

Perl> print for map{ 
    $_->[0] 
} sort{ 
    $a->[1] cmp $b->[1] 
} map{ 
    [ $_, join'', m[type=(\S+)\s+author=(\S+)] ] 
} @toSort;;
name=Document1.doc type=Excel author=bAuthor
name=Document1.doc type=Excel author=dAuthor
name=Document1.doc type=Text author=cAuthor
name=Document1.doc type=Word author=aAuthor
name=Document1.doc type=Word author=eAuthor

Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Sorting with multiple keys
created: 2006-02-03 03:21:24
you can use [cpan://Sort::Key] to generate fast multikey sorting functions:
# Create a keysort function that uses two strings as keys:

use Sort::Key::Maker ss_keysort => qw(string string);


# And then use it.
# The first argument passed is the subroutine 
# to extract the keys from the data:

my @sorted_by_type_and_author =
  ss_keysort {
                /^name=.*? type=(.*?) author=(.*?)$/;
                ($1, $2)
             } @lines;

Re: Sorting with multiple keys
created: 2006-02-06 00:05:55
All, Thanks for solutions..

perlmonks.org content © perlmonks.org and BrowserUk, GrandFather, Mandrake, salva

prlmnks.org © 2006 edmund von der burg (eccles & toad)

v 0.03