Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations TouchToneTommy on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

identifying duplicate array values. 1

Status
Not open for further replies.

jez

Programmer
Apr 24, 2001
370
VN
hello

I am trying to loop through an array and pick out only individual values.

The following code i wrote works but misses a value in the middle of the array for some reason. I have tried a few things but I can't find why it misses this particular value.

The array values are;-

0801
1001
0301
0801
0601
0701
0701
0701
0701
0701
0701
0701

and the array is called @omonths

here is the code;-

@sortedomonths = sort @omonths;
for($i=0;$i<@sortedomonths;$i++) {
if ($sortedomonths[$i] eq $sortedomonths[$i+1]) {$i+=1;}
else {push @indmonths, $sortedomonths[$i];}
}

the results of a print command produce this;-

0301
0601
0701
1001


as you see 0801 is missing, but I can't figure out why.

Any help would be great.


Cheers

Jez

:)
 
# I would cheat and use a hash....
# Each time you get a duplicate, it just overwrites any previous instances of that one.

foreach ('0801','1001','0301',
'0801','0601','0701','0701',
'0701','0701','0701','0701','0701')
{ $unique{$_} = 1; }

@sorted_unique_months = sort(keys(%unique));



HTH


keep the rudder amid ship and beware the odd typo
 
The problem is that you are skipping elements in the array. The problem is the line:

if ($sortedomonths[$i] eq $sortedomonths[$i+1]) {$i+=1;}
If the array is a duplicate, you add 1 to the array index in the &quot;if&quot; line and you also add 1 in the for loop. Thus the two 0801s get skipped. An easy fix is to change the line to:
if ($sortedomonths[$i] eq $sortedomonths[$i+1]) {next;}


 
Cheers GoBoating and Raider2001,

I have used the 'next' option, mainly because the array is handy because the data is just generated lists of 4 digits like that.

Thanks again

Jez

:)
 
Two alternative methods, that are quite compact:

1) Using a hash slice:

Code:
@unique{@unsorted} = @unsorted;
@sorted = sort keys %unique;

2) Using grep

Code:
@sorted = sort grep { ! $seen{$_}++ } @unsorted;

The second method has the advantage of populating the
Code:
%seen
hash with the number of occurences of each item in
Code:
@unsorted

Happy coding, cheers NEIL :cool:


 
Is there a way to find the non-unique (duplicates) instead ?

-Thanks!
 
If you just want to know which values are dupicated, and not how many times they are duplicated you can do either of the following
Code:
map { $seen{$_}++ } @array;
my @dupes = grep { $seen{$_} > 1 } keys %seen;

# Or a less standard way

my @dupes = keys %{{ map { $_, $_ } grep { $seen{$_}++ } @array }};
jaa
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top