mmontemuro has asked for the wisdom of the Perl Monks concerning the following question:

I need to sort a data structure by name. Any ideas of how this would be done? I've attached a simple program to simulate what I want done.
#!/usr/bin/perl -w use strict; my $ref=''; my $entry=''; my @records=(); my @sorted=(); sub getmydata { my($name,$project,$hours) = @_; my ($tester) = { name => $name, project => $project, hours => $hours }; return $tester; } while(<DATA>) { $ref = getmydata(split); #Space delimited by default push(@records, $ref); #We then sort this array } #This is where I need help #Sort into sorted array by name. Array should contain list in sorted o +rder by name # #print out data structure in sorted order by Name foreach $entry (@sorted) #Returns ref, must deref it, { print "NAME:$entry->{name}\n"; print "JOB:$entry->{project}\n"; print "HOURS:$entry->{hours}\n"; print "--------------\n"; } __END__ Mike Plumber 80 Laura Programmer 60 Mark Sales 70 Jeremy Cook 65

Replies are listed 'Best First'.
Re: Sort lists/Data Structures
by McDarren (Abbot) on Dec 05, 2008 at 20:25 UTC
    What you are looking for is the sort function.

    However, I think you are over complicating things somewhat.
    Consider the following:

    #!/usr/bin/perl use strict; use warnings; my %people; while (my $line = <DATA>) { chomp($line); my ($person, $occupation, $hours) = split /\s+/, $line; $people{$person}{occupation} = $occupation; $people{$person}{hours} = $hours; } for my $person (sort keys %people) { print "Name: $person\n"; print "Job: $people{$person}{occupation}\n"; print "Hours: $people{$person}{hours}\n"; print "------------------\n"; } __DATA__ Mike Plumber 80 Laura Programmer 60 Mark Sales 70 Jeremy Cook 65
    Does this do what you want?

    Cheers,
    Darren :)

      For a few elements, I agree with what you have. My actual program has about 60+ elements. It gets a bunch of fields from a database. So in this case, I felt that a data structure returning a reference is easier to work with. So your previous solution works just fine to display these records. Thanks again for your speedy response.
Re: Sort lists/Data Structures
by kennethk (Abbot) on Dec 05, 2008 at 20:22 UTC

    First, to make posted code legible, you need to use <code> tags.

    You could try writing your own test for the sort method, which would solve your issue. A second approach, assuming your names are unique, would be to create a new hash with names as keys and references to records as values. You could then sort your keys and cycle through that array on the hash, i.e.

    my %hash_by_name; for (@records) { $hash_by_name{$_->{name}} = $_; } my @sorted_names = sort keys %hash_by_name; while (@sorted_names) { push @sorted, $hash_by_name{shift @sorted_names}; }

    Note the above will fail if you have repeat names.

      This was what I was missing, creating a hash of the key to sort which contained the structure address. Thanks, I got it working the way I wanted.
Re: Sort lists/Data Structures
by lightoverhead (Pilgrim) on Dec 05, 2008 at 20:56 UTC
    it's easy to sort even with your structure: @sorted=sort {$a->{name} cmp $b->{name}}@records;