in reply to Hash key counting

BlackJudas,
Like Aristotle, I do not understand what you are trying to accomplish, so let me explain in plain English what your code is doing so maybe it will help

  • You loop through every value of the @discounts array
  • If any value is numerically equivalent to 1, you get the current number of keys in %columns
  • You then add one to that number
  • Finally, you create a new entry in %columns whose key is the previous number of keys + 1, and the value is set to 1

    If you are expecting the %columns to increase then you may want to add a print statement that says:
    print "Discount == 1\n";
    Then check to see if this is happening as often as you expect.

    Note: If you are not going to use the value of the hash, you could save time by setting it to undef as in
    $columns{$key_num} = undef;
    And if you are going to do that, you might as well use an array instead of a hash, but there is probably something else you are using it for.

    I hope this explains what is going on.

    Cheers L~R

    Update: Modified entire reply as I realized the problem is probably with the outside loop

  • Replies are listed 'Best First'.
    Re: Re: Hash key counting
    by blackjudas (Pilgrim) on Apr 21, 2003 at 21:51 UTC
      Ver nice response Limbic, my apologies for being unclear. I've replied to BrowserUK above and hope the explanation sheds some light on my problem.

      The points you've made above are exactly what I've intended the code to do.

      I have checked the results as you have suggested by using print, what seems to happen is that the result of $key_num seems to stay the same and it works for the last iteration of the loop, the last key number in %columns is always incremented by one, though it seems that no matter how many times I loop, the last inserted key is overwritten, seems to me (I used print) that $key_num always returns the same number.


      BlackJudas
        blackjudas,
        The following code works fine for me - just as you want it to:
        #!/usr/bin/perl -w use strict; my %columns = ( 1 => 1, 2 => 1, 3 => 1, 4 => 1 ); my @discounts = qw( 1 2 1 3 1 4 1 5); for my $discount (@discounts) { if ($discount == 1) { my $key_num = scalar keys %columns; $key_num++; $columns{$key_num} = 1; } } print "$_ : $columns{$_}\n" foreach (keys %columns);

        Cheers - L~R

        Update: As others have pointed out - if %columns is already populated and the keys are not sequential starting from one - you run the risk of this not working. This could also be a problem if you delete keys elsewhere. For instance:

        17 => 1 3 => 1
        There are 2 keys, add one you get 3, but guess what - 3 already exists. You may want to check to see if the key exists. I think there is a better way to accomplish whatever you are trying to do.

        Then it is quite likely that you a missing one key value (as has been hinted at several places in this thread). What keys are in the hash when this code isn't working? If the keys are, for example, 1, 2, 3, 5, 6, and 7, then you have 6 keys and you will use "7" as your next key (since "4" is missing). Such would explain your problem.

        This is part of why so many have complained about not understanding your code. Part of your code assumes that all keys from 1 through N will be present (and no others) which means an array would be a more appropriate data structure (and wouldn't be susceptible to this type of bug). And you have yet to explain how you use this hash elsewhere, so we are forced to guess why you'd choose what appears to be a very poorly fitting solution, so we can't help much with fixing it.

                        - tye