Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

Replace Array Elements with Hash Values

by shortyfw06 (Beadle)
on Jun 13, 2012 at 16:38 UTC ( #976009=perlquestion: print w/ replies, xml ) Need Help??
shortyfw06 has asked for the wisdom of the Perl Monks concerning the following question:

I am having difficulty replacing array elements with hash values using the following script. $string appears 8 times in my output file. I want to replace the first occurance with $header{1} amd the second with $header{2} and so on. Any help is appreciated! Thanks!

use Tk; use strict; use warnings; my $mw=new MainWindow; my $filename; my $string; my @data; my $n; my %header = ("FHT_neg45","FHT_0","FHT_45","FHT_90","OHT_neg45","OHT_0 +","OHT_45","OHT_90"); my $button = $mw->Button(-text=>"temp", -command=> \&button)->pack(); MainLoop; sub button { #Read BJSFM_out.prn into an array @data $filename="BJSFM_out.prn"; open(OUTPUT, "< $filename") or die "Can't find allowables.txt!"; $string="Laminate Strain Allowables"; @data=<OUTPUT>; $n=1; for (@data) { if ($_ eq $string) { s/$_/$header{$n}/; $n++; } } open (FILE, '>temp.txt'); print FILE @data; close FILE; }

Comment on Replace Array Elements with Hash Values
Download Code
Re: Replace Array Elements with Hash Values
by toolic (Chancellor) on Jun 13, 2012 at 16:48 UTC
    Each element of @data has a newline (\n) at the end. You need to chomp before your comparison, but then need to add \n back before you print.

    Update: I also think you really should use an array instead of a hash: @headers.

Re: Replace Array Elements with Hash Values
by stevieb (Chaplain) on Jun 13, 2012 at 16:58 UTC

    Good morning,

    From what I can tell, you need an array, not a hash:

    #!/usr/bin/perl use Tk; use strict; use warnings; my $mw=new MainWindow; my @header = ("FHT_neg45","FHT_0","FHT_45","FHT_90","OHT_neg45","OHT_0 +","OHT_45","OHT_90"); my $button = $mw->Button(-text=>"temp", -command=> \&button)->pack(); MainLoop; sub button { #Read BJSFM_out.prn into an array @data my $filename="BJSFM_out.prn"; open my $fh, '<', $filename or die "Can't find allowables.txt! $!" +; my $string="Laminate Strain Allowables"; my @data=<$fh>; my $n = 0; for (@data) { chomp; if ($_ eq $string) { $data[$n] = $header[$n]; $n++; } } open my $write_fh, '<', 'temp.txt' or die $!; print $write_fh @data; close $write_fh; }

    I also made a few other changes... three-arg form of open(), lexically scoped most of your vars within the sub (instead of having them global), and changed from using a bareword file handle to a scalar one.

    Also, if you have a more current version of Perl, you can change that for loop to using while/each on the array:

    while ( ( my $iter, $elem ) = each @data ){ if ( $elem eq $string ){ $data[ $iter ] = $header[ $iter ]; } }

    Update: added in chomp per toolic's point in his above post. I can't test this code as I don't have Tk installed. I've also included the file open check that I missed, as noted by morgon below.

      Two further improvements:

      First, toolic is right about the need for chomping, so

      my @data = map { chomp; $_ } <$fh>;
      and of course check the open:
      open my $write_fh, '<', 'temp.txt' or die $!;

        I tried to run the following and it replaces $string with %header rather than $string with $header[0], $header1, etc. Also, I thought my print command would add the newlines but it doesn't.

        use Tk; use strict; use warnings; my $mw=new MainWindow; my @header = ("FHT_neg45","FHT_0","FHT_45","FHT_90","OHT_neg45","OHT_0 +","OHT_45","OHT_90"); my $button = $mw->Button(-text=>"temp", -command=> \&button)->pack(); MainLoop; sub button { #Read BJSFM_out.prn into an array @data my $filename="BJSFM_out.prn"; open my $fh, '<', $filename or die "Can't find $filename!"; my $string="1DO YOU WANT INSTRUCTIONS?"; my @data= map {chomp; $_ } <$fh>; my $n=0; for (@data) { if ($_ eq $string) { $data[$n] = $header[$n]; $n++; } } open my $write_fh, '>', 'temp.txt' or die $!; print $write_fh join " ",@data,"\n"; close $write_fh; }
        Just an observation. List::MoreUtils has a function apply which does the chomp and passes the modified, (line less the newline), line to @data

        my @data= apply {chomp} <$fh>;.

        Chris

        Update: Or more simply, chomp(my @data = <$fh>);

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://976009]
Approved by stevieb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others rifling through the Monastery: (8)
As of 2015-01-27 20:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My top resolution in 2015 is:

















    Results (202 votes), past polls