Link to home
Start Free TrialLog in
Avatar of David Aldridge
David AldridgeFlag for United States of America

asked on

problem with a foreach loop

I have the following  code.  After the first foreach loop, I have the data I want in @temp.  I've printed it, there are just a lot of dupes.  I can't figure out why my second foreach loop isn't getting rid of the dupes. The regex isn't matching $var and I don't get anything on the print.

#!/usr/bin/perl

@vxdisk = `vxdisk -o alldgs list`;
foreach ( @vxdisk ) {
        if ( m{.*\d+\s+(\S+)\s+.*} ) {
                if ( $1 =~ m{auto} ) {
                        next;
                }
                push ( @temp, "\n$1" );
        }
}

# Get rid of the dupes
foreach $var ( @temp ) {
        if ( !grep( m{$var}, @temp ) ) {
                print "$var\n";
                # push ( @dg_list, "$var" );
        }
}

#print "@dg_list\n";
Avatar of David Aldridge
David Aldridge
Flag of United States of America image

ASKER

Actually, I see why the print command wouldn't work, but the push I have commented out doesn't work either. Nothing gets pushed to @dg_list.
Ok, I figured out I was using the wrong array on the grep, but I'm still getting dupes.
Got it!  

#!/usr/bin/perl

@vxdisk = `vxdisk -o alldgs list`;
foreach ( @vxdisk ) {
        if ( m{.*\d+\s+(\S+)\s+.*} ) {
                if ( $1 =~ m{auto} ) {
                        next;
                }
                push ( @temp, "\n$1" );
        }
}

# Get rid of the dupes
foreach $var ( @temp ) {
        if ( !grep( m{$var}, @dg_list ) ) {
                # print "$var\n";
                push ( @dg_list, "$var" );
        }
}

print "@dg_list\n";
If you see a better way to do this, please post it.  I'll leave it up for a while.
Avatar of ozo
push ( @dg_list, "$var" ); is commented out, so it will never execute

If there are no meta characters in $var, grep( m{$var}, @temp ) will always succeed

For a better way, you may want to look at
perldoc -q "How can I remove duplicate elements from a list or array"
I uncommented it on the second piece of code.  It's working now, but if you can see a better way to do it, I'll take it.
It also gives me a blank line at the top which I would prefer to get rid of when I print @dg_list. I know it's from the push ( @temp, "\n$1" ), but can't figure out how to get rid of it.
a better way from the perldoc faq
my %seen=();
 @dg_list = grep !$seem{$_}++ @temp;

or, if order does not matter
my %seen;
@seen{@temp}=();
print for keys %seen;
ASKER CERTIFIED SOLUTION
Avatar of ozo
ozo
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
This is what I get from the first one and the code is right below it.

testbox-[root]/home/share/daldrid/work/Perl/sapwork> vxdisk_chk
Array found where operator expected at vxdisk_chk line 14, near "++ "
        (Missing operator before  ?)
syntax error at vxdisk_chk line 14, near "++ @temp"
Execution of vxdisk_chk aborted due to compilation errors.


my %seen=();
@dg_list = grep !$seen{$_}++ @temp=();
print "@dg_list\n";
exit;
@dg_list = grep !$seen{$_}++, @temp;
I don't get an error with it now, but @dg_list get nothing in it.

Your other suggestion for getting rid of the blank at the top is great.
This worked.

%hash = map {$_, 1 } @temp;
print "$_\n" for keys %hash;


Thanks ozo.