Question on perl function

Hello, I'm tyring to use perl to reference to a hash and then return the contents of ther hash in an array. Within this function that I am building I am entering in the data in the hash in the form last name, firstname, age. When the value is returned I want the value to come out of the array age,firstname, lastname. I also tyring to get it to sort. Since I know more about sorting arrays I was thinking of just sorting the array instead of the hash. Right now, the info is not reading the hash correctly. This is what I have code wise:

%people = ("Richardson, Greg" -> 22, "Zog, Mike" -> 23, "Boston, Doug -> 24, "Rudolph, Josh" -> 25, "Fritz, Stacy" -> 26)

foreach @child (keys %people) {
print "$child, $people{$child}
}

@people = keys %people, values %people
@sorted_people = sort{lc($b) cmp (lc($a)} @people
print @sorted_people

Any help would be great


DancingFighterGAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ultimatemikeCommented:
You can actually sort the hash without creating an array.  Try this:


%people = ("Richardson, Greg" -> 22, "Zog, Mike" -> 23, "Boston, Doug -> 24, "Rudolph, Josh" -> 25, "Fritz, Stacy" -> 26)



foreach ( sort { lc($b) cmp lc($a)}  keys (%people) ) {

      my @names = split /, /;
      my $age = $people{$_};

}


so $names[0] will have the last name, and $names[1] will contain the first name.
0
FishMongerCommented:
ultimatemike showed you an excelent method for for doing the sort (in reverse order).  However, instead of splitting the name into an array, I'd use 2 scalars and I'd make sure the names were translated to titlecase.  My example uses to print statements to show the difference in style of output.


%people = ("richardson, greg" => 22, "Zog, Mike" => 23, "Boston, doug" => 24, "Rudolph, Josh" => 25, "Fritz, Stacy" => 26);

foreach $person ( sort { lc($a) cmp lc($b)}  keys (%people) ) {

   $person =~ s/(\w+)/\u$1/g;  # translate to titlecase
   ($last, $first) = split /, /, $person;

   print "$person is $people{$person} years old\n";
   print "$first $last is $people{$person} years old\n\n";
}
0
FishMongerCommented:
If you really need to use an array, then instead of those print statements, you'd push the info onto the array.

Like this:

push @last_first, "$person $people{$person}";
push @first_last, "$first $last $people{$person}";

Then you can print the array somewhere else in your script. like this:

print "$_\n" foreach @last_first;
print "$_\n" foreach @first_last;
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

kanduraCommented:
Why not change your data to another structure? I like using record-style hashes for this, because it adds flexibility in both sorting and displaying.
I would use something like:
$person = {
    firstname => 'Greg',
    lastname => 'Richardson',
    age         => 22
};

First I'll convert your %people hash into an array of person records:
my @people = ();
while(my ($k, $v) = each %people) {           # loop over elements
    my ($lname, $fname) = split /, /, $k, 2;    # split the key into name parts
    push @people, {                                      # add anonymous hash to the array
        firstname => $fname,
        lastname  => $lname,
         age         => $v
    };
}

now you can sort your array on one or more keys of the records.

examples:
# sort by last name
my @ns_people = sort {
     $a->{lastname} cmp $b->{lastname}
    } @people;

# sort by last name, firstname ascending, age descending
my @lfa_people = sort {
     $a->{lastname} cmp $b->{lastname} ||        # first sort on last name
     $a->{firstname} cmp $b->{firstname} ||        # next on first name
     $b->{age}          <=> $a->{age}                   # finally, on age descending
    } @people;

you can put whatever criteria into the sort { } block that you need. (Including doing a case insensitive sort).

Outputting your data becomes much more flexible too, since you have separate fields for every part of the person.
Example:
foreach(@lfa_people) {
    printf "Age: %d, name: %s %s\n", $_->{age}, $_->{firstname}, $_->{lastname};
}

Also it makes it easy to filter your data. Say you would only want the people with age 25:
@tf_people = grep { $_->{age} == 25 } @lfa_people;

HTH,

Kandura
0
DancingFighterGAuthor Commented:
Quick question FishMonger, is there any way I can print out the hash itself so I can show the original has data and then the array version?
0
jmcgOwnerCommented:
You could do

use Data::Dumper;

print Dumper( \%people, \@lfa_people);

0
FishMongerCommented:
After looking over the script that I posted, I noticed an error I made reguarding the the titlecase.  Here's the corrected script that also prints out the hash before and after the sorting (as well as the sorted array) and uses the CSV formating (I think you were wanting) .


%people = (
           "richardson, greg" => 22,
           "zog, mike" => 23,
           "Boston, doug" => 24,
           "Rudolph, Josh" => 25,
           "Fritz, Stacy" => 26
);

print "Prior to sorting the hash\n";
print "\t$_ $people{$_}\n" foreach (keys %people);


print "\nAfter sorting the hash\n";
foreach $person ( sort { lc($a) cmp lc($b)}  keys (%people) ) {
   ($last, $first) = split /, /, $person;
   $last =~ s/(\w+)/\u$1/;  # translate to titlecase
   $first =~ s/(\w+)/\u$1/;  # translate to titlecase
   print "\t$people{$person},$first,$last\n";
   push @first_last, "$people{$person},$first,$last";
}

print "\nSorted hash put into an array\n";
print "\t$_\n" foreach @first_last;
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
DancingFighterGAuthor Commented:
Thanks FishMonger. I could not figure out how to print out the hash right. Thanks again. :)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Perl

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.