in reply to Re: concatenation 2 values then pushing to a hash_ref
in thread concatenation 2 values then pushing to a hash_ref

sorry, I didn't mean to make you guess.

GOAL:find the common Italian number in both files that contains both Spanish and French translations (did that). Then,I added complexity to my learning by adding other number translations (german, english) and build the match file to contain these.

lastly, to dump the numbers that don't have a matching Italian number in any.

things I'd hope to learn.

1) HASH_REF 2) Print HASH_REF 3)conditionals (if,else,define) with hash_ref 4)Concat ( now, I know needs a (.) THANKS TO YOU! although I saw an example where it didn't and that's what I followed) 5) play with SPLIT to remove =,spaces:/ and stuff.

Questions for clarity

:

EXAMPLE snippet1 I modeled my concat syntax, why the Difference? why mine didn't work?

chomp; my($col1,$col2,$rest)=split(/\t/); my $ckey="$col1$col2" #<= NO PERIOD!

question 2, what does this piece do?can you explain your addition of "!"? I'm thinking, if the $num is UNDEF then go into loop...is this thinking correct?

if (!defined $num){

Output of Not a match of Italian number in either file has a printing bug I would like to remove. Please note, there is no French number in spot1 and so it gives ",," instead, how to remove these?

nouve =>nueve,,neun uno =>uno,,eins

I build my hash as follows:

Italian => Spanish, French, whatever

so in this case, one number is not found in the other and so the spot is just filled with ",,"

NEED HELP:how to order the numbers on output?, any ideas???

CORRECTED my hash structure like this since concat didn't print like I wanted

my ($ita,$fren,$num1,$num2)= split(/[=\s,]+/); #creates col of num +bers $hash{$ita}[1]=$fren; #now hash_ref format will look like this: it +a=> spa , fren #define if there is are numbers in position 3 and 4 concat to posi +tion 3 if (defined ($num1)){ $hash{$ita}[3]=$num1; # % looks like this: Ita=> Spa, Fren, R +andNUM[3] } if (defined $num2){ $hash{$ita}[4]=$num2; # % looks like this Ita=> Span,Fren, Ra +ndnum[3]?(ifdefined), Randnum[4] } }

somehow I feel there is a better way to do this...can hash of hashes be better? I don't know yet, I guess I need to learn that next...

GRAZIE MILLE

Replies are listed 'Best First'.
Re^3: concatenation 2 values then pushing to a hash_ref
by Aldebaran (Curate) on Jun 12, 2015 at 09:57 UTC

    As a humble scribe, I welcome the opportunity to assist you in this matter. It's a challenge for me to understand exactly what you intend, and it is for you as well. The exercise of writing and debugging perl helps us to specify our intent, in particular, when informed by the script, input, and output. Having read your response, I've changed all three. I changed the input back to what you posted in the original post. I made several changes to the script; it's best just to list it before commenting too much:

    use strict; use diagnostics; use warnings; use autodie qw(open close); use Data::Dumper; use 5.010; #declare variables my %hash; my $data; #opening Files using autodie to cut typing... open my $in, '<', "Test_Data_RandNumbers.txt"; open my $in1, '<', "Test_Data_More_RandNumbers.txt"; open my $out, '>', "OUT_Test_Data_Ita_SpanFren_rest.txt"; open my $out1, '>', "OUT_Test_data_NO_match_SpanFren.txt"; #open my $out2,'>' , "./Test_Data_Out_None_Match.txt"; while (<$in>) { #data manipulation to clean up ='s and ,'s #dieci = diez, zehn -->worse case, remove spaces and = and comma; #quattro = quatro -->only one number with spaces or not in from of = +... chomp; my ( $ita, $spa, $num ) = split(/[=\s,]+/); say "values are $ita $spa $num"; $hash{$ita}[0] = $spa; #what about if there is no $num at position 1 in 1st file? if ( defined $num ) { $hash{$ita}[2] = $num; } } close $in; while (<$in1>) { chomp; my ( $ita, $fren, $num1, $num2 ) = split(/[=\s,]+/); say "values are $ita $fren $num1 $num2"; $hash{$ita}[1] = $fren; #now hash's format will look like this: ita +=> spa fren #define if there are numbers in position 3 and 4 concat to positio +n 3 if ( defined($num1) and defined($num2) ) { $hash{$ita}[3] = "$num1 $num2"; } elsif ( defined $num1 ) { $hash{$ita}[3] = $num1; } } close $in1; foreach my $ita ( keys %hash ) { if ( $hash{$ita}[0] and $hash{$ita}[1] ) { print $out "$ita =>", join( ',', @{ $hash{$ita} } ), "\n"; } else { print $out1 "$ita =>", join( ',', @{ $hash{$ita} } ), "\n"; } } print Dumper(\%hash); close $out; close $out1;

    I use the feature "say" to understand what values are going into the script. I get a lot of undefined values, but they don't "sink the ship," as it were. I re-wrote my concatenation syntax to mimic yours--I added a space in the middle of a quoted string--yet I wonder if this is actually what you want as far as the logic is concerned. Let's take a look at the output:

    C:\Users\Fred\Desktop\pm>type OUT* OUT_Test_Data_Ita_SpanFren_rest.txt sei =>seis,six,,six quattro =>quatro,quatre,,four due =>dos,deux,zwei,two dieci =>diez,dix,zehn sette =>siete,sept,sechs,seven sechs cinque =>cinco,cinq,funf,funf five undici =>once,onze,elf,eleven tre =>tres,trois,drei,drei three tredici =>trece,treize,dreizehn,thirteen dreizehn OUT_Test_data_NO_match_SpanFren.txt dodici =>doce uno =>uno,,eins nouve =>nueve,,neun otto =>ocho

    More informative might be the output from STDOUT:

    $VAR1 = { 'sei' => [ 'seis', 'six', '', 'six' ], 'quattro' => [ 'quatro', 'quatre', undef, 'four' ], 'due' => [ 'dos', 'deux', 'zwei', 'two ' ], 'dieci' => [ 'diez', 'dix', 'zehn' ], 'sette' => [ 'siete', 'sept', 'sechs', 'seven sechs' ], 'dodici' => [ 'doce' ], 'uno' => [ 'uno', undef, 'eins' ], 'nouve' => [ 'nueve', undef, 'neun' ], 'cinque' => [ 'cinco', 'cinq', 'funf', 'funf five' ], 'otto' => [ 'ocho' ], 'undici' => [ 'once', 'onze', 'elf', 'eleven' ], 'tre' => [ 'tres', 'trois', 'drei', 'drei three' ], 'tredici' => [ 'trece', 'treize', 'dreizehn', 'thirteen dreizehn' ] };

    I ask you to inspect the output. Aside from the commas, is this what you want? It seems to me that the commas is a cosmetic issue, while determining the fundamental logic is primary. What's more, I don't think you want concatenation, as it produces duplicate values. But, as a humble scribe, I have no means to scry.

      thanks for he help!, it's an enormous thing to see the data structure by using dump

      yes, the contact was a means to learn a new trick(althought, all in perl right now is a new trick to me) I got that " " made the trick work where I didn't do that. although, I am wondering with a question,

      what is the difference between these:as far as data goes.any forseeable issues

      colunm 3 will have the "$1num $num2" $hash{$ita}= "$num1 $num2";

      vs col3 has $num1

      if (defined $num1){$hash{$ita}3=$num1} and

      column4 has now $num2

      if (defined $num2){$hash{$ita}4=$num2}

      yes, I think concat is not what I want now that I know this and I have changed the code myself now too

      true, the comma is cosmetic and I was looking for an exercise in manipulating printing to learn a new technique. I am sure I will get A LOT more practice on print the way I want stuff all summer