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
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."
| [reply] [Watch: Dir/Any] |
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
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
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
| [reply] [Watch: Dir/Any] [d/l] |
|
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
| [reply] [Watch: Dir/Any] [d/l] |
|
|
|
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 | [reply] [Watch: Dir/Any] [d/l] |
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)? | [reply] [Watch: Dir/Any] [d/l] |
|
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
| [reply] [Watch: Dir/Any] [d/l] |
|
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
| [reply] [Watch: Dir/Any] [d/l] |
|
|
|