Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
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 (Hermit) 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 lurking in the Monastery: (7)
As of 2014-11-23 03:36 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    My preferred Perl binaries come from:














    Results (128 votes), past polls