LearningCpp LearningCpp - 2 months ago 8
Perl Question

Split the data with 3 delimiters and store it in 2 separate arrays at a time

I have data with 3 delimiters (: , and ;) And in the data : and ; appear only once

__DATA__

1:X,Y,X,A,B;C,D,E,F
2:A,C,B,D
3:W,R,T,E;E


Step 1:


Split by : and build a hash


Step 2:


Split by , and store every comma separated value in a array till we find ;


Step 3:


Everything that follows ; would be in another array


From the above data, i am trying to store all the values before ; in array A and everything on right in array B

Output
A = [X,Y,X,B,A,B,C,D,W,R,T,E] B=[C,D,E,F,E]


Below is the code i tried

my (@A,@B);
sub Compare_results
{
my %result_hash = map { chomp; split ':', $_ } <DATA> ; #split by colon and futher split by , and ; if any (doing it in insert_array)
foreach my $key ( sort { $a <=> $b } (keys %result_hash) )
{

@A = split ",", (/([^;]+)/)[0], $result_hash{$key};
@B = split ",", (/;([^;]+)/)[0], $result_hash{$key};
print Dumper \@A,\@B;
}

}


But this is not producing the any results, The output arrays are empty
Whats the right approach of splitting data by , and ; at a time store in separate array
Is there also a way split data by three delimiters (one split for building up a hash ) at one shot

Thanks

Answer

Many problems: open needs a file name, not filehandle contents (unless DATA contains the file name, which it doesn't). To keep the values in the arrays, use push, not assignment - you can't assign to two arrays at the same time, anyway, as the first one eats everything. Also, doing everything in one command might be possible, but definitely not readable and maintainable.

#!/usr/bin/perl
use warnings;
use strict;

my $fh = *DATA{IO};
my (@A, @B);                                            # The comments just fix
                                                        # the stupid SO syntax highlighter.
my %result_hash = map { chomp; split /:/ } <$fh>;       #/
for my $key (sort { $a <=> $b } keys %result_hash) {
    my ($left, $right) = split /;/, $result_hash{$key}; #/
    push @A, split /,/, $left;                          #/
    push @B, split /,/, $right // q();
}

use Data::Dumper; print Dumper(\@A, \@B, \%result_hash);

__DATA__
1:X,Y,X,A,B;C,D,E,F
2:A,C,B,D
3:W,R,T,E;E