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

Hello Monks, I am trying to read a file and save the information into a hash , I am able to do that but when I try to update the file again I am trying not to insert the same information again so I am checking the hash to see if there is a key defined in there with the information I am inserting . It doesn't seem to do the check correct eventhough I am inserting the same data .
data ---- one two three three one two one one three my %currentData; open (DATA, "data") or die ""; my $line; while ($line = <DATA>) { chomp $line; $currentData{$line}++; } close DATA; # Now after reading the user inputs for updating the file as follow my @updateInfo; my @updateInfo = "$inputONE\t$inputTwo\t$inputThree"; if ( $currentData{$line} ) { print "the info exists already\n"; exit; +} else { print " your info is being saved and the file is updated\n"; ex +it; }
it always goes to the else , why ????

Replies are listed 'Best First'.
Re: Hash problem
by matija (Priest) on Mar 06, 2004 at 18:18 UTC
    It always goes to the else because the data in your @updateInfo (why did you make it an array, and not a scalar, BTW? You're putting a single value into it) is not in any of the three lines of the file.

    If you want the hashes to work in a case-independent way, access them as $hash{lc $key}.

    Oh, and you are assigning the info to @updateInfo and testing $currentData{$line}. You should assign the test data to $line or test $currentData{$updateInfo[0]}.

Re: Hash problem
by TomDLux (Vicar) on Mar 06, 2004 at 19:24 UTC
    # Now after reading the user inputs for updating the file as follow my @updateInfo; my @updateInfo = "$inputONE\t$inputTwo\t$inputThree"; if ( $currentData{$line} ) { print "the info exists already\n"; exit; +} else { print " your info is being saved and the file is updated\n"; ex +it;

    Now, $inputONE is undefined, so it stringifies as an empty string: ''. Same with $inputTwo and $inputThree.

    It might be better to format the three variable names in corresponding styles. $inputONE has the differentiating number parrt in ALL CAPS, while the other two just capitalize the first letter of the numeric portion.

    If you ever have variables with numbers in the name, this is a red flag that you should probably be using an array. It is no problem that you use elements 1, 2 & 3 ...after all, it is so common to deal with the 'first' element being in slot zero. Alternately, you can simply ignore array slot zero, if 1, 2 & 3 are important to you.

    Mind you, are you locked on three elements? Can it change? All the more reason to use an array.

    If the number of elements might change, you don't want to get stuck hard coding the value you assign to @updataInfo. join() is your friend.

    @updateInfo = join( "\t", @inputs );

    So that sets $updateInfo[0]. What were you planning to put in $updateInfo[1], $updateInfo[2], etc.? So maybe it should by $updateInfo instead of @updateInfo.

    Of course, the final step is testing whether the update info is already present in the array:

    if ( $currentData{$updateInfo} ) { ......

    PostScript: I don't find Data or Info very meaningful words to use in variable names. After all, every variable contains data and info. Od course, this is just a test snippet, so it's hard to come up with meaningful names.

    --
    TTTATCGGTCGTTATATAGATGTTTGCA

Re: Hash problem
by Crian (Curate) on Mar 06, 2004 at 23:42 UTC
    I don't know exactly what your problem is, but perhaps this code could solve it? :)

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; my @lines; while (<DATA>) { my %line; ++$line{$_} for split /\s+/; push @lines, { %line }; } print Dumper \@lines; __DATA__ one two three three one two one one three


    it prints

    $VAR1 = [ { 'three' => 1, 'one' => 1, 'two' => 1 }, { 'three' => 1, 'one' => 1, 'two' => 1 }, { 'three' => 1, 'one' => 2 } ];