in reply to Filling in missing values in an array

The solution below uses the flip-flop operator to see if we are in a NULL section or not. If we just started seeing NULL's that array index is noted. When we have seen the first number past the NULL's, a sub is called to go back fill the correct numbers into the array.
#!/usr/bin/perl -w use strict; my $data = '4 NULL NULL NULL 5 1 NULL NULL 2 NULL 6'; my @data = split(/\s+/,$data); my $iFirstNULL; my $cur_index=0; foreach (@data) { if (my $num = /NULL/.../\d/) { $iFirstNULL = $cur_index if $num == 1; insertValues($iFirstNULL-1,$cur_index,\@data) if $num =~ /E0/; } $cur_index++; } print "@data"; #prints 4 4 4.5 5 5 1 1 2 2 4 6 sub insertValues { my ($istart, $iend, $aref) = @_; my $pos = $istart+1; my $beginNum = $aref->[$istart]; my $endNum = $aref->[$iend]; while ($aref->[$pos] eq 'NULL') { if ($pos-$istart < $iend-$pos) # closer to start { $aref->[$pos] = $beginNum; } elsif($pos-$istart > $iend-$pos) # closer to end { $aref->[$pos] = $endNum; } else # directly in middle { $aref->[$pos] = ($endNum + $beginNum)/2; } $pos++; } }

Replies are listed 'Best First'.
Re^2: Filling in missing values in an array
by roboticus (Chancellor) on Jun 29, 2011 at 12:35 UTC

    Marshall:

    I was toying with splice and made an amusing variation:

    #!/usr/bin/perl -w use strict; my $data = '4 NULL NULL NULL 5 1 NULL NULL 2 NULL 6'; my @data = split(/\s+/,$data); my $iFirstNULL; my $cur_index=0; foreach (@data) { if (my $num = /NULL/.../\d/) { $iFirstNULL = $cur_index if $num == 1; splice @data, $iFirstNULL, $cur_index-$iFirstNULL, newVals(@data[$iFirstNULL-1 .. $cur_index]) if $num =~ /EO/; } $cur_index++; } print "@data\n"; #prints 4 4 4.5 5 5 1 1 2 2 4 6 sub newVals { my ($leftVal, $rightVal, $num) = ($_[0], $_[-1], scalar(@_)-2); # Left half of the return list is $leftVal, right half is $rightVa +l my @ret = (($leftVal) x int($num/2), ($rightVal) x int($num/2)); # Insert the average in the center for an odd-sized number of null +s splice @ret, int($num/2), 0, ($leftVal+$rightVal)/2 if $num&1; return @ret; }

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.