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

for an undefined amounts of users (n), I want to create a hash that holds a user ID (which would be in the order 1, 2, ... , n | n != 1 or 2) and a value that would be pulled from an array with n entries for sorting into decending order by the value. any good ideas? Thanks for helping a newbie!!

Replies are listed 'Best First'.
Re: hash creation.
by Petruchio (Vicar) on Jan 03, 2001 at 19:30 UTC
    Greetings! :-)

    Your post generated some very interesting discussion... principly because some very smart people didn't understand it. We want to help you, but you seem not to have a very solid grasp of our vocabulary yet, and nobody's quite sure what you mean. It would help if you restated your question, and gave the context; if you talk about it, we may be able to figure out what you're meaning to say.

    Also, it seems that this might be a homework assignment. Understand, we do not do homework assignments, though we are always happy to help with them. If it's homework, tell us, and we'll set you in the right direction. If it's not, tell us what it's for, so that we can make better suggestions.

    And though it's not a requirement, if you're serious about learning Perl, you might want to create an account and stick around. This community is open to all skill levels, and we'd be pleased to have you.

    Good luck!

      haha.. thanks for the push in the correct direction!
       
      Anyways, this isn't a homework problem, let me assure you of that straight away. What I'm doing is an online hockey pool for my work.
       
      Currently, it takes the picks that a certain user made out of a data file and assigns a total amount of "points" to the user based on how many points their players have gotten (which is determined completely independantly from this part of the script). This value is stored in an array at this point, because the user ID is, at this point, the array index of the amount of "points." A hash here is useless (right?).
       
      Anyways, after all the "points" values for all the users are set into the array, I think it'd be best to put these values into a hash that also holds the user id, and then sort the hash by the "points" values.
       
      Perhaps there's something wrong with my reasoning?
       
      I'll come clean: I've only be using PERL for 3 days now, and I've only been programming for about a year or so. That's why I tried to explain it more in a mathematical light than a programming one.
       
      Thanks for your help! I'll be setting up an account shortly.
        If I've got a grasp on your problem, what you want to do is sort a list of IDs by their associated point values. You certainly could do that with a hash, where the IDs are keys and the points are values, but given your set of IDs you don't need to; an array would work well for the whole process.
        #!/usr/local/bin/perl -w use strict; my @scores = ( undef, undef, undef, # skip IDs 0, 1, and 2 7, 28, 19, 3, 36, ); my @ids_by_score = sort { $scores[$b] <=> $scores[$a] } # higher scores first 3 .. $#scores; # IDs 3 to max ID print "ID: Score\n"; for my $id (@ids_by_score) { printf "%2d: %5d\n", $id, $scores[$id]; }
        The main difference is that you get the list of IDs as 3 .. $#scores, instead of with keys(%scores) if it were a hash.
Re: hash creation.
by Fastolfe (Vicar) on Jan 03, 2001 at 19:24 UTC
    If the user ID is numeric, starting at or near zero, and will only be incrementing, why not use an array instead? Don't use a hash unless you need to be able to store more complex information in the hash key (like a string), or if you're using numbers, if the numbers are from a random distribution (as an array will create elements to fill in the gaps). That way the array is immediately "sorted", to make it descending, just reverse it, and things are much easier to deal with.

    If you have a legitimate need to use hashes in this case, just use sort against the hash keys:

    @descending_keys = sort { $b <=> $a } keys %hash;
      I guess I didn't define the problem good enough :)
       
      Anyways, I really need the user ID to stick with the value during the sort so that I can display the user name and the value on a page with the highest value first, and so on, so I think that I have to use a hash. If this isn't the case, please inform me!
       
      Regardless, the problem I'm having is with setting the values for the undetermined amount of users. If I knew or could limit the amount of users, things would be a lot simpler, but the script should be able to do this on its own.
        Your post led me to believe your user ID's would be numeric. I don't think I quite understand what all of the "1, 2, ... , n | n != 1 or 2" is supposed to mean. ID's incrementing but starting at 3? If your intent is to associate a username and an ID, by all means a hash is what you want. See the documentation for sort, and perhaps How do I sort a hash (optionally by value instead of key)?. To find the largest ID, you can use 'max' from List::Util on the values of the %hash, but you're better off storing that in a variable unless your script only needs to use this once.

        Regardless, this is pretty basic hash usage stuff. You would benefit more from a book like Learning Perl or the Perl Cookbook.