1

I have a small program that I am trying to format the output. The results get loaded in to an array - I am just having trouble formating the printing out the array into a certain format.

#!/usr/bin/perl
use strict ;
use warnings ;
my @first_array ;
my @second_array  ;
my @cartesian ;

while (<>) {
    my $first_input =  $_ ;
    @first_array = split(' ', $first_input) ;
    last ;
}
while (<>) {
    my $second_input = $_ ;
    @second_array = split(' ', $second_input) ;
    last ;
}


while(my $first=shift(@first_array)) {
    push(@cartesian, $first) ;
        my $second = shift(@second_array)  ;
        push(@cartesian, $second ) ;

}

print "This is the merged array: @cartesian\n" ;

When I enter this in, I get this:

$ ./double_while2.pl
1 2 3
mon tue wed
This is the merged array 1 mon 2 tue 3 wed

what I want to print out is :

"1", "mon",
"2", "tue" ,
"3", "wed",

or alternately:

1  => "mon",
2  => "tue",
3  => "wed,
2
  • 4
    Tip: while (<>) { my $first_input = $_ ; ... last ; } is a weird way of doing my $first_input = <>; ... Commented Nov 2, 2016 at 6:07
  • thank you ikegami - you are the man Commented Nov 2, 2016 at 20:09

4 Answers 4

4

May I suggest a hash, since you are pairing things

my %cartesian; 
@cartesian{ @first_array } = @second_array;

print "$_ => $cartesian{$_}\n" for sort keys %cartesian;

A hash slice is used above. See Slices in perldata

The arrays that you build had better pair up just right, or there will be errors.

If the goal is to build a data structure that pairs up elements, that can probably be done directly, without arrays. More information would help to comment on that.

Sign up to request clarification or add additional context in comments.

Comments

2

Try to use hash instead.

for my $i(0..$#first_array){
    $hash{$first_array[$i]} = $second_array[$i];
 }

or else, you want format without using hashes, try as follows

for  (my $i = 0; $i < $#cartesion/2; $i++) {
      my $j  = ($cartesion/2) + $i;
      print "$cartesion[$i] $cartesion[$j] \n";

   } 

Comments

0

From your question and your code, I suppose that you are a lovely new 'victim' to perl ~ To merge two arrays with same lengh, I suggeest using 'map' to simplify your code:

my @cartesian = map {$first_array[$_], $second_array[$_]} 0..$#first_array;

and to format print style , you can define a subroutine to meet your different requirements:

sub format_my_array{
   my $array_ref = shift;
   my $sep = shift;
   print $array_ref->[$_],$sep,$array_ref->[$_+1],"\n" for grep {! ($_%2)} 0..$#$array_ref;
}

Now, you can try calling your subroutine:

format_my_array(\@cartesian, " => ");

or

format_my_array(\@cartesian, " , ");

Now, you get what you want~

You may have noticed that some intermediate concepts are used in this answer, don't doute , that's exactly what I'm trying to introduce you to ~

May you the great happiness in learning perl ~

Comments

0

The trick is to go with Perl's strengths instead of fighting against them:

#!/usr/bin/perl

use strict;
use warnings;
# For say()
use 5.010;

my @first_array  = split ' ', <>;
my @second_array = split ' ', <>;

if (@first_array != @second_array) {
  die "Arrays must be the same length\n";
}

my @cartesian = map { $first_array[$_], $second_array[$_] } 0 .. $#first_array;

for (0 .. $#cartesian / 2) {
  say "$cartesian[$_*2] => $cartesian[$_*2+1]";
}

But, it gets much easier still if you use a hash instead of an array for your merged data.

#!/usr/bin/perl

use strict;
use warnings;
# For say()
use 5.010;

my @first_array  = split ' ', <>;
my @second_array = split ' ', <>;

if (@first_array != @second_array) {
  die "Arrays must be the same length\n";
}

my %cartesian;
@cartesian{@first_array} = @second_array;

for (sort keys %cartesian) {
  say "$_ => $cartesian{$_}";
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.