Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Hash Question

by mmittiga17 (Scribe)
on Jan 10, 2011 at 22:06 UTC ( #881549=perlquestion: print w/replies, xml ) Need Help??

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);


    $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"; }

      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>

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://881549]
Approved by ELISHEVA
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (2)
As of 2023-02-05 20:54 GMT
Find Nodes?
    Voting Booth?
    I prefer not to run the latest version of Perl because:

    Results (32 votes). Check out past polls.