in reply to Deleting records from an array

Use splice, although, some might not recommend it. I use it extensively, when working with arrays, since, it greatly simplifies and shortens your code. Also, it's very efficient.

Your code:
for my $key (keys %coll_key_hash) { foreach my $rec (@recs_read) { my @fields = split(/\|/, $rec); if ($fields[0] eq '010') { if ($fields[3] =~ $key) { $print_record = 1; if ($key ne $prev_key) { $prev_key = $key; print_record ("CUST-BEG|$seq\n",' '); } print_record ("$rec\n",'c'); } else { $print_record = 0; } } else { if ($print_record) { print_record ("$rec\n",'c'); } } } }
First, I would like to simplify it, in order to work with it easier:
for my $key (keys %coll_key_hash){ for my $rec (@recs_read){ my @fields = split(/\|/, $rec); if($fields[0] eq '010'){ $print_record = 0; if($fields[3] =~ $key){ #shouldn't this be /$key/ ? $print_record = 1; unless($key eq $prev_key){ $prev_key = $key; print_record ("CUST-BEG|$seq\n",' '); } } } if($print_record){ print_record ("$rec\n",'c'); } } }
The splice algorhythm to delete an array record and to check for loop iteration consistence:
for my $key (keys %coll_key_hash){ for(my $recIdx = 0; $recIdx < scalar @recs_read; $recIdx++){ #check, if redo overflowed the end of an array: next if(($recIdx + 1) > scalar @rec_read); my $rec = $recs_read[$recIdx]; my @fields = split(/\|/, $rec); if($fields[0] eq '010'){ $print_record = 0; if($fields[3] =~ $key){ #shouldn't this be /$key/ ? $print_record = 1; unless($key eq $prev_key){ $prev_key = $key; print_record ("CUST-BEG|$seq\n",' '); } } } if($print_record){ print_record ("$rec\n",'c'); #Delete one record at the specified index: splice(@recs_read, $recIdx, 1); #Since the record at the current index is deleted, the new + record shifted to the same index, so we test it again: redo; } } }

Replies are listed 'Best First'.
Re^2: Deleting records from an array
by Anonymous Monk on Dec 22, 2014 at 14:10 UTC
    Also, it's very efficient.
    I was curious about that and decided to test it. Splice is more efficient then I thought but it's still not as fast as undef with big arrays. So with arrays of 1000 element they're equal:
    x $ perl cmp.pl -t 1000 -s 1000 Rate splice undef splice 287/s -- -3% undef 296/s 3% --
    10000 elements and undef becomes a bit faster:
    $ perl cmp.pl -t 1000 -s 10000 Rate splice undef splice 19.4/s -- -21% undef 24.7/s 27% --
    40000 elements and undef significantly faster:
    $ perl cmp.pl -t 100 -s 40000 Rate splice undef splice 2.41/s -- -43% undef 4.24/s 76% --
    Even with the most favorable conditions for splice they're about equal:
    $ perl cmp.pl -t 1000000 -s 10 Rate splice undef splice 18678/s -- -7% undef 20190/s 8% --