http://qs1969.pair.com?node_id=881549

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

I have a file I need to parse that contains multiple lines for an account number. I want to print out just the first occurrence for each account number. I stink at using Hash Keys and values. What I am getting is the last occurrence of each account in the file. Any help would be great. example: 1234,ladjfljadflajdkfalkjdfladjf 1234,ouoquldjljadfjodjfladfljdfljaljf 1234,oueuodlcmcmdldjtljfjldjfljdfljldjf 1234,ladjfljadflajdkfalkjdfladjf 5678,aldkjfldajfljadfljdalfjladjwerwer 5678,uulkdjfljdfljdalfjaiieieieiiwpppp Just want to print out 1234,ladjfljadflajdkfalkjdfladjf 1234,ladjfljadflajdkfalkjdfladjf

@ACCTS = ("1234", "5678", "6959"); open(IN,"InFile.txt"); %acct=""; while (defined($line = (<IN>))){ foreach $x (@ACCTS) { if ($line =~/$x/){ $acct{$x} = ($x,$line); } } } foreach $key (sort keys %acct){ print "$acct{$key}\n"; }

Replies are listed 'Best First'.
Re: Hash Question
by tj_thompson (Monk) on Jan 10, 2011 at 22:17 UTC

    The problem is that you are updating your hash every time you see a new line. You need to update the hash conditionally on whether you've already seen the data you're interested in. Try changing your line:

    acct{$x} = ($x,$line);

    To:

    $acct{$x} = ($x,$line) unless exists $acct{$x}

    This way you only update your hash if you've never seen the account number before.

Re: Hash Question
by ELISHEVA (Prior) on Jan 10, 2011 at 22:14 UTC

    Only assign a value to the hash key if (!exists($acct($s)). This will be true only for the first line so only the first line will be saved in your hash.

Re: Hash Question
by state-o-dis-array (Hermit) on Jan 10, 2011 at 22:23 UTC
    I'm going to go strictly off your description, as what you said you want to print out doesn't seem to match the description as I understand it.

    I would just do something like this:

    @ACCTS = ("1234", "5678", "6959"); open(IN,"InFile.txt"); %acct=""; while (defined($line = (<IN>))){ foreach $x (@ACCTS) { if ($line =~/$x/){ #only print the first line we see for each account unless( exists $acct{$x} ){ print "$line\n"; $acct{$x}++; } } } }
    Or if you need to store all the data for other purposes:
    @ACCTS = ("1234", "5678", "6959"); open(IN,"InFile.txt"); %acct=""; while (defined($line = (<IN>))){ foreach $x (@ACCTS) { if ($line =~/$x/){ push(@{$acct{$x}},$line); } } } foreach $key (sort keys %acct){ print "$key,$acct{$key}[0]\n"; }
      %acct="";

      Initializing a hash (and a non-lexical one for good measure) with a key of an empty string with the default value of undef produces a warning if warnings are enabled, as they almost always should be – along with strictures.

      use warnings; use strict;

      Thank you all very much for the help. With your help I learned something new and got my script to work. <\p>