http://qs321.pair.com?node_id=694391

harishnuti has asked for the wisdom of the Perl Monks concerning the following question:


Just an update on the question i asked earlier

actually iam stuck with the below in my project , so iam putting the following piece of code from my main script
while (<process file delimited by ~ symbol>){ @data = split(/\~/,$_); # will have around 30 elems # $data[23] will have user preference column selection # user enters 3,3-7,4,9-13 etc anything he desires $data[23] =~ s/-/\.\./; # convert - to .. perl syntax # 23rd elements contains the range entered by user # for ex: 2,3-8,11-20 # i need to extract only above range ignoring rest push(@range,eval $array[23]); # i expanded here @range = map { --$_ } @range; # decrementing since array starts + from 0 # @range = grep { !$seen{$_}++ } @range; # remove duplicates in + case user enters like 2,1-10 etc # @range = sort { $a <=> $b } @range; # Sort thee indices in as +cending order like 1,2,3,4,5,6 and so on my @finalarray = @data[@range];


iam having trouble when i print final array i get all junk values, iam sure something is wrong or there can be another good approach to achieve above.


you help is highly appreciated and helpful for me.

i have spent quite sometime on above today

Replies are listed 'Best First'.
Re: Splicing Arrays on pre-defined indices
by psini (Deacon) on Jun 27, 2008 at 16:38 UTC

    My advice is: use Text::CSV to parse the original csv file and to create the new one.

    You can avoid worrying about escaping quotes, non ascii characters and such

    Rule One: "Do not act incautiously when confronting a little bald wrinkly smiling man."

Re: Splicing Arrays on pre-defined indices
by injunjoel (Priest) on Jun 27, 2008 at 18:33 UTC
    Here is something to try,
    my $line = "1!2!3!4!5!6!7!8!9"; my @arr = split /!/, $line; my @indices = (2,5..8); #just remember indexing starts at 0. print join(" : ", @arr);#original print "\n"; print join(" : ", @arr[2,5..8]);#explicit print "\n"; print join(" : ", @arr[@indices]);#predefined
    Output
    1 : 2 : 3 : 4 : 5 : 6 : 7 : 8 : 9 3 : 6 : 7 : 8 : 9 3 : 6 : 7 : 8 : 9

    Update
    Just thought of another quick way to do this...
    my $line = "1!2!3!4!5!6!7!8!9"; my @arr = split /!/, $line; my @exclude = (2,5..8); #just remember indexing starts at 0. #set the elements to nothing and then filter them out. @arr[@exclude] = (); @arr = grep $_, @arr;
    Just another thought,

    -InjunJoel
    "I do not feel obliged to believe that the same God who endowed us with sense, reason and intellect has intended us to forego their use." -Galileo
      Thanks a lot for it.. but indeed the above is otherway meaning we are considering indices on what we want rather exclusion , but my requirement is we should exclude certain col by specifying indices( for ex: here @incides)..
      my $line = "1!2!3!4!5!6!7!8!9"; # Original line read my @arr = split /!/, $line; my @indices = (2,5..8); #i need these indices to be sliced print join(" : ", @arr);#original splice (@arr,@indices,1); # something like this iam trying to achieve print "\n"; # i might be having 30 to 40 col of which i dont need 4 to 5, so its b +etter i slice 4 to 5 col's instead of considering 30 col's
        my @exclude = (2,5..8); my @exclude_lkup; $exclude_lkup[$_] = 1 for @exclude; my $line = "1!2!3!4!5!6!7!8!9"; my @arr = split /!/, $line; my @filtered = map $arr[$_], grep !$exclude_lkup[$_], 0..$#arr; print("@filtered\n"); # 1 2 4 5

      Just an update on the question i asked earlier

      actually iam stuck with the below in my project , so iam putting the following piece of code from my main script
      while (<process file delimited by ~ symbol>){ @data = split(/\~/,$_); # will have around 30 elems # $data[23] will have user preference column selection # user enters 3,3-7,4,9-13 etc anything he desires $data[23] =~ s/-/\.\./; # convert - to .. perl syntax # 23rd elements contains the range entered by user # for ex: 2,3-8,11-20 # i need to extract only above range ignoring rest push(@range,eval $array[23]); # i expanded here @range = map { --$_ } @range; # decrementing since array starts + from 0 # @range = grep { !$seen{$_}++ } @range; # remove duplicates in + case user enters like 2,1-10 etc # @range = sort { $a <=> $b } @range; # Sort thee indices in as +cending order like 1,2,3,4,5,6 and so on my @finalarray = @data[@range];

      iam having trouble when i print final array i get all junk values, iam sure something is wrong or there can be another good approach to achieve above

      you help is highly appreciated and helpful for me

      sorry for not providing sample data, because file is pretty large and question is straight forward, i have spent quite sometime on above today
Re: Splicing Arrays on pre-defined indices
by waldner (Beadle) on Jun 27, 2008 at 16:41 UTC
    How can $processline[17] contain comma separated values if the file itself is a CSV? Please provide an example using actual data. Also, do you want to skip rows (as it would seem since you have a variable called $unwantedrows) or columns (as would be logical)?
      Iam sorry if my first post confused a bit... Ok here is what iam doing... ** COBOL Program which extracts information from database to flat file with ! as delimiter... ** My perl programs reads the flat file and should convert it to CSV file based on value at Col 17( contains clients names) ** one CSV file per client
      my %filehash = (); while (<>){ @pline = split (/\!/,$_); my $keycolumn = $pline[15]; # based on this col values split files unless ($filehash{$keycolumn}){ $filehash{$keycolumn}{name} = $pline[15]; open $filehash{$keycolumn}{handle},">$filehash{$keycolumn}{n +ame}; # open distinct file handles for each distinct value found in c +ol 15 } print {$filehash{$keycolumn}{handle}} @pline; } # In the above code iam considering all col's , but my new requirement + is , for some rows i should only some predifined col's which can 1, +3,5,6,7 i.e. i need slice these indices from @pline before writing it + into corresponding file
        Thx for reply, let me make my question rather more simple
        # Assume below line is read from a file my @array = qw/i will skip some words here using splice/; print "Array before deletion \n"; print join("-->",@array),"\n"; print "Enter the Indices which you like to skip\n"; chomp($indices=<STDIN>); # i entered 2,4,5 my @indices = split(/\,/,$indices); foreach (@indices){ splice (@array,$_,1); # remove element } print "Updated array is as below \n"; print join("==>",@array),"\n"; # if there is any easy way of doing above in short , i can integrate i +n my existing code