### CODE TO REMOVE records with id =~ /000$/
my @return_set = (
{id => 'CA2345H000'},
{id => 'CA2345H100'},
{id => 'CA2345H030'},
{id => 'CA235H000'},
{id => 'CA234H001'},
);
_exclude_special_session(\@return_set);
use Data::Dumper;die 'DDDEBUG' . Dumper(\@return_set);
sub _exclude_special_session {
my $recordset = shift;
my $i;
for my $record (@{$recordset}) {
if ($record->{id} =~ /000$/) {
delete $recordset->[$i];
}
$i++;
}
}
##### HERE IS THE OUTPUT
DDDEBUG$VAR1 = [
undef,
{
'id' => 'CA2345H100'
},
{
'id' => 'CA2345H030'
},
undef,
{
'id' => 'CA234H001'
}
];
> The folllowing code is supposed to remove entries from
> @return_set that end in '000'. It leaves an undef in
> the array instead of removing the whole element. What
> fix would be best to achieve an array without 'undef'
> elements? Thanks for any help!
@new_set = grep { $_->{id} !~ m/000$/ } @return_set;
>The folllowing code is supposed to remove entries from
>@return_set that end in '000'. It leaves an undef in
>the array instead of removing the whole element. What
>fix would be best to achieve an array without 'undef'
>elements? Thanks for any help!
>
>
>### CODE TO REMOVE records with id =~ /000$/
>my @return_set = (
> {id => 'CA2345H000'},
> {id => 'CA2345H100'},
> {id => 'CA2345H030'},
> {id => 'CA235H000'},
> {id => 'CA234H001'},
>);
>
>_exclude_special_session(\@return_set);
>
>use Data::Dumper;die 'DDDEBUG' . Dumper(\@return_set);
>
>sub _exclude_special_session {
> my $recordset = shift;
> my $i;
> for my $record (@{$recordset}) {
> if ($record->{id} =~ /000$/) {
splice (@{$recordset},$i,1);
> }
> $i++;
> }
>}
>
>
-sln
mp> The folllowing code is supposed to remove entries from
mp> @return_set that end in '000'. It leaves an undef in
mp> the array instead of removing the whole element. What
mp> fix would be best to achieve an array without 'undef'
mp> elements? Thanks for any help!
mp> delete $recordset->[$i];
did you read the docs on delete? it is meant for use on hashes and the
docs say it leaves an undef in an array. to actually remove an element
or a set of elements from an array, splice is used. as someone else
posted, your problem is best solved by grep.
uri
--
Uri Guttman ------ u...@stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------
From the perlsyn documentation:
If any part of LIST is an array, "foreach" will get very confused if
you add or remove elements within the loop body, for example with
"splice". So don’t do that.
Martien
--
|
Martien Verbruggen | Since light travels faster than sound,
first...@heliotrope.com.au | is that why some people appear bright
| until you hear them speak?
>On Sat, 07 Nov 2009 12:37:25 -0800,
> s...@netherlands.com <s...@netherlands.com> wrote:
>> On Sat, 07 Nov 2009 14:47:41 -0500, monkeys paw <us...@example.net> wrote:
>>
>>>sub _exclude_special_session {
>>> my $recordset = shift;
>>> my $i;
>>> for my $record (@{$recordset}) {
>>> if ($record->{id} =~ /000$/) {
>>
>> splice (@{$recordset},$i,1);
>>
>>> }
>>> $i++;
>>> }
>
>From the perlsyn documentation:
>
> If any part of LIST is an array, "foreach" will get very confused if
> you add or remove elements within the loop body, for example with
> "splice". So don�t do that.
>
>Martien
Oh, I didn't see the LIST context.
Either one of these then.
for ( my $i=0; $i<@{$recordset}; $i++ ) {
$recordset->[$i]{id} =~ /000$/ and splice (@{$recordset},$i--,1);
}
my $i = 0;
while ( $i<@{$recordset} ) {
$recordset->[$i++]{id} =~ /000$/ and splice (@{$recordset},--$i,1);
}
-sln
This is quadratic. The usual linear-time idiom is to replace the
$i-th element by the (removed) last one.
Yours,
Ilya
Better to just reverse the list:
for ( my $i = $#$recordset; $i >= 0; --$i ) {
$recordset->[ $i ]{ id } =~ /000$/ and splice @$recordset, $i, 1;
}
for my $i ( reverse 0 .. $#$recordset ) {
$recordset->[ $i ]{ id } =~ /000$/ and splice @$recordset, $i, 1;
}
John
--
The programmer is fighting against the two most
destructive forces in the universe: entropy and
human stupidity. -- Damian Conway
Not sure what you mean by this. This form of splice shrinks the array
by what, something like a memmove() in a typless way.
The solution is to do your own itterating.
Shrink with no adjustment:
for (@{$recordset}) {
$recordset->[$i]{id} =~ /000$/ and splice (@{$recordset},$i,1);
}
Shrink with adjustment:
for ( my $i=0; $i<@{$recordset}; $i++ ) {
$recordset->[$i]{id} =~ /000$/ and splice (@{$recordset},$i--,1);
}
-sln
>s...@netherlands.com wrote:
>> On Sun, 8 Nov 2009 08:05:07 +1100, Martien Verbruggen <martien.v...@invalid.see.sig> wrote:
>>
>>> On Sat, 07 Nov 2009 12:37:25 -0800,
>>> s...@netherlands.com <s...@netherlands.com> wrote:
>>>> On Sat, 07 Nov 2009 14:47:41 -0500, monkeys paw <us...@example.net> wrote:
>>>>
>>>>> sub _exclude_special_session {
>>>>> my $recordset = shift;
>>>>> my $i;
>>>>> for my $record (@{$recordset}) {
>>>>> if ($record->{id} =~ /000$/) {
>>>> splice (@{$recordset},$i,1);
>>>>
>>>>> }
>>>>> $i++;
>>>>> }
>>>From the perlsyn documentation:
>>> If any part of LIST is an array, "foreach" will get very confused if
>>> you add or remove elements within the loop body, for example with
>>> "splice". So don�t do that.
>>>
>>> Martien
>>
>> Oh, I didn't see the LIST context.
>> Either one of these then.
>>
>> for ( my $i=0; $i<@{$recordset}; $i++ ) {
>> $recordset->[$i]{id} =~ /000$/ and splice (@{$recordset},$i--,1);
>> }
>>
>> my $i = 0;
>> while ( $i<@{$recordset} ) {
>> $recordset->[$i++]{id} =~ /000$/ and splice (@{$recordset},--$i,1);
>> }
>
>Better to just reverse the list:
>
>for ( my $i = $#$recordset; $i >= 0; --$i ) {
> $recordset->[ $i ]{ id } =~ /000$/ and splice @$recordset, $i, 1;
>}
>
>
>for my $i ( reverse 0 .. $#$recordset ) {
> $recordset->[ $i ]{ id } =~ /000$/ and splice @$recordset, $i, 1;
>}
>
>
>
>
>John
Yes, much better to start at the end, don't have to move so much data.
-sln
I would simply use a grep() instead of rolling my own code. This is
exactly the scenario it was made for.
jue
>The folllowing code is supposed to remove entries from
>@return_set that end in '000'. It leaves an undef in
>the array instead of removing the whole element.
" Note that deleting array elements in the middle of an array will not
shift the index of the ones after them down--use splice() for that."
BTW, if delete $array[$index] worked the same as splice @array,$index,1
you'd have another problem, because your $i would be wrong after the first
delete.
--
Shmuel (Seymour J.) Metz, SysProg and JOAT <http://patriot.net/~shmuel>
Unsolicited bulk E-mail subject to legal action. I reserve the
right to publicly post or ridicule any abusive E-mail. Reply to
domain Patriot dot net user shmuel+news to contact me. Do not
reply to spam...@library.lspace.org
That would be the one.
I've been away from Perl for quite a while. I sometimes forget these
idioms.
I suppose it wouldn't be hard to write a method akin to Python's
built-in filter(), but I almost took for granted that Perl doesn't have
it. The bonus to lurking on c.l.perl ;)
Thanks.