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

I have the following code. I want to take the resulting $name and $number arrays (I haven't pushed them into arrays yet, but you get the idea), and remove multiple names--leaving only one name that is the average value of the multiples. Also, if one of the values is 999, I want that to be added as zero (999 is used in the subsequent program as a null value).
my %name2number; open DATA, "query.txt" or die "$!"; $/ = "\n"; while (<DATA>) { my ($key, $value) = (split); $name2number{$key} = $value; } for my $name (@orf) { my $number; if ($name2number{$name}) { $number = $name2number{$name}; } else { $number = 999; } print "$name => $number\n"; }
Thanks. Evan

Replies are listed 'Best First'.
Re: Removing multiple values
by demerphq (Chancellor) on Sep 07, 2001 at 00:52 UTC
    I want to take the resulting $name and $number arrays (I haven't pushed them into arrays yet, but you get the idea),

    Is that a safe assumption to make? :-)
    What for instance was @orf in your code?

    Anyway try something like this:

    my %averages; open DATA, "query.txt" or die "$!"; $/ = "\n"; while (<DATA>) { #split on consecutive sequences of spaces/tabs #i dont like naked splits.. personally... my ($key, $value) = split(" ",$_); $averages{$key}->[0]+= $value; $averages{$key}->[1]++; } map { $averages{$_}=$averages{$_}->[0]/$averages{$key}->[1]; $averages{$_}|=999; print "$key => $averages{$_}\n"; } keys %averages;
    UPDATE: Fixed split call to read split(" ",$_) instead of split(/s+/,$_) Which isnt the same thing at all. Also read Hofmators excellent comment on this issue in this reply

    Hope that helps.

    Oh and you should in future indent your code properly, post your data and make no assumptions about what us the readers know understand or whatever about it and what you are trying to do.

    Thats called pot luck. :-)

    Yves
    --
    You are not ready to use symrefs unless you already know why they are bad. -- tadmc (CLPM)

      Good suggestions, demerphq++. A small detail

      my ($key, $value) = split(/s+/,$_); #i dont like naked splits.. personally...
      It's OK to not like this bare split, but you should be aware that your version is behaving differently if $_ has leading whitespace, so to write it long and correctly, do this:
      $_ = " key value"; my ($key, $value) = split(" ",$_); # note: this behaves differently my ($key, $value) = split(/ /,$_);
      Try it out and see the difference, this is documented in split as well.

      -- Hofmator