Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > Deleting blank elements from a list

Reply
Thread Tools

Deleting blank elements from a list

 
 
Just in
Guest
Posts: n/a
 
      07-02-2004
If I do this:-

use strict;
use warnings;

my @Arr1 = split /\D+/, $Str1;
my @Arr2 = split /\D+/, $Str2;

foreach my $i(0..$#Arr1)
{
foreach my $j(0..$#Arr2)
{
if($Arr1[$i] eq $Arr2[$j])
{
delete $Arr2[$j];
}
}
}

In some instances @Arr2 ends up looking like this ('', '', 'Value3',
Value4', '')

How can I make @Arr2 = ('Value3', 'Value4') i.e. $#Arr2 == 1
rather than 4?

Cheers,
Just in


 
Reply With Quote
 
 
 
 
Bob Walton
Guest
Posts: n/a
 
      07-02-2004
Just in wrote:

> If I do this:-
>
> use strict;
> use warnings;
>
> my @Arr1 = split /\D+/, $Str1;
> my @Arr2 = split /\D+/, $Str2;
>
> foreach my $i(0..$#Arr1)
> {
> foreach my $j(0..$#Arr2)
> {
> if($Arr1[$i] eq $Arr2[$j])
> {
> delete $Arr2[$j];
> }
> }
> }
>
> In some instances @Arr2 ends up looking like this ('', '', 'Value3',
> Value4', '')
>
> How can I make @Arr2 = ('Value3', 'Value4') i.e. $#Arr2 == 1
> rather than 4?
>
> Cheers,
> Just in



You could use the splice() function instead of delete() to remove
element from @Arr2 instead of just undef'ing them like delete() does:

perldoc -f splice

But you should really revamp your entire algorithm, since it is way slow
(order n^2). Maybe something like:

{
my %h;
@h{@Arr2}=(0..$#Arr2);
delete @h{@Arr1};
@Arr2=sort {$h{$a}<=>$h{$b}} keys %h;
}

You could apply the Schwarzian Transform to the sort to further improve
the efficiency.

--
Bob Walton
Email: http://bwalton.com/cgi-bin/emailbob.pl

 
Reply With Quote
 
 
 
 
Gunnar Hjalmarsson
Guest
Posts: n/a
 
      07-02-2004
Just in wrote:
> If I do this:-
>
> use strict;
> use warnings;
>
> my @Arr1 = split /\D+/, $Str1;
> my @Arr2 = split /\D+/, $Str2;
>
> foreach my $i(0..$#Arr1)
> {
> foreach my $j(0..$#Arr2)


To increase efficiency and prevent uninitialized warnings:

foreach my $j (reverse 0..$#Arr2)

> {
> if($Arr1[$i] eq $Arr2[$j])
> {
> delete $Arr2[$j];


splice @Arr2, $j, 1;

> }
> }
> }
>
> In some instances @Arr2 ends up looking like this ('', '',
> 'Value3', Value4', '')
>
> How can I make @Arr2 = ('Value3', 'Value4') i.e. $#Arr2 == 1
> rather than 4?


See suggestions above. You should also study

perldoc -q duplicate

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
 
Reply With Quote
 
John W. Krahn
Guest
Posts: n/a
 
      07-02-2004
Just in wrote:
>
> If I do this:-
>
> use strict;
> use warnings;
>
> my @Arr1 = split /\D+/, $Str1;
> my @Arr2 = split /\D+/, $Str2;


You should probably use the match operator for that so that you don't
get an empty string as the first element of the array.

my @Arr1 = $Str1 =~ /\d+/g;
my @Arr2 = $Str2 =~ /\d+/g;


> foreach my $i(0..$#Arr1)
> {
> foreach my $j(0..$#Arr2)
> {
> if($Arr1[$i] eq $Arr2[$j])
> {
> delete $Arr2[$j];
> }
> }
> }
>
> In some instances @Arr2 ends up looking like this ('', '', 'Value3',
> Value4', '')


It would look more like (undef, undef, 'Value3', 'Value4', undef)


> How can I make @Arr2 = ('Value3', 'Value4') i.e. $#Arr2 == 1
> rather than 4?


This will do what you want:

my $regex = qr[\b@{[ join '|', $Str1 =~ /\d+/g ]}\b];
my @Arr2 = grep !/$regex/, $Str2 =~ /\d+/g;



John
--
use Perl;
program
fulfillment
 
Reply With Quote
 
John W. Krahn
Guest
Posts: n/a
 
      07-02-2004
Just in wrote:
>
> If I do this:-
>
> use strict;
> use warnings;
>
> my @Arr1 = split /\D+/, $Str1;
> my @Arr2 = split /\D+/, $Str2;


You should probably use the match operator for that so that you don't
get an empty string as the first element of the array.

my @Arr1 = $Str1 =~ /\d+/g;
my @Arr2 = $Str2 =~ /\d+/g;


> foreach my $i(0..$#Arr1)
> {
> foreach my $j(0..$#Arr2)
> {
> if($Arr1[$i] eq $Arr2[$j])
> {
> delete $Arr2[$j];
> }
> }
> }
>
> In some instances @Arr2 ends up looking like this ('', '', 'Value3',
> Value4', '')


It would look more like (undef, undef, 'Value3', 'Value4', undef)


> How can I make @Arr2 = ('Value3', 'Value4') i.e. $#Arr2 == 1
> rather than 4?


This will do what you want:

my $regex = qr[\b(?:@{[ join '|', $Str1 =~ /\d+/g ]})\b];
my @Arr2 = grep !/$regex/, $Str2 =~ /\d+/g;


John
--
use Perl;
program
fulfillment
 
Reply With Quote
 
dutone
Guest
Posts: n/a
 
      07-03-2004
Gunnar Hjalmarsson <(E-Mail Removed)> wrote in message news:<(E-Mail Removed)>...
> Just in wrote:
> > If I do this:-
> >
> > use strict;
> > use warnings;
> >
> > my @Arr1 = split /\D+/, $Str1;
> > my @Arr2 = split /\D+/, $Str2;
> >
> > foreach my $i(0..$#Arr1)
> > {
> > foreach my $j(0..$#Arr2)

>
> To increase efficiency and prevent uninitialized warnings:
>
> foreach my $j (reverse 0..$#Arr2)
>
> > {
> > if($Arr1[$i] eq $Arr2[$j])
> > {
> > delete $Arr2[$j];

>
> splice @Arr2, $j, 1;
>
> > }
> > }
> > }
> >
> > In some instances @Arr2 ends up looking like this ('', '',
> > 'Value3', Value4', '')
> >
> > How can I make @Arr2 = ('Value3', 'Value4') i.e. $#Arr2 == 1
> > rather than 4?

>
> See suggestions above. You should also study
>
> perldoc -q duplicate



You suggested....

To increase efficiency and prevent uninitialized warnings:
foreach my $j (reverse 0..$#Arr2)

Can you tell me how this will increase efficiency?

Thanks
 
Reply With Quote
 
Gunnar Hjalmarsson
Guest
Posts: n/a
 
      07-03-2004
dutone wrote:
> Gunnar Hjalmarsson wrote:
>>To increase efficiency and prevent uninitialized warnings:
>>
>> foreach my $j (reverse 0..$#Arr2)

>
> Can you tell me how this will increase efficiency?


Fewer iterations under certain conditions, and (I think) more accurate
result. Please consider this code:

my $Str1 = '1 2 3 4 5';
my $Str2 = '1 1 2 2 6';
my $iter;

my @Arr1 = split /\D+/, $Str1;
my @Arr2 = split /\D+/, $Str2;

for my $i (0..$#Arr1) {
for my $j (0..$#Arr2) {
if ($Arr1[$i] eq $Arr2[$j]) {
splice @Arr2, $j, 1;
}
$iter++;
}
}

print "Left in \@Arr2: @Arr2\n";
print "$iter iterations\n";

Besides a couple of "uninitialized" warnings it outputs:
Left in @Arr2: 1 2 6
18 iterations

But if you change

for my $j (0..$#Arr2) {

to

for my $j (reverse 0..$#Arr2) {

it outputs:
Left in @Arr2: 6
11 iterations

(and no warnings).

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
blank CD-R and blank DVD-R not recognized by Vista 64 Ultimate =?Utf-8?B?R3JlZyBLaXJrcGF0cmljaw==?= Windows 64bit 13 11-07-2007 12:23 PM
Appending a list's elements to another list using a list comprehension Debajit Adhikary Python 17 10-18-2007 06:45 PM
Removing elements from a list that are elements in another list Adam Hartshorne C++ 2 01-27-2006 07:47 AM
deleting elements from a list in a for loop flupke Python 5 10-29-2004 02:54 PM
Retrieving then deleting elements of a list (references) Arvin Portlock Perl Misc 2 12-10-2003 05:47 PM



Advertisments