For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > May 2004 > @UNIQUE=unique(@REDUNDANT);









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author @UNIQUE=unique(@REDUNDANT);
Jason Dusek

2004-05-18, 11:30 pm

Hi,

Is there an easy way to get all the unique elements of an array? i.e. is
there some module or function that does that sort of thing?
--
-- Jason Dusek ("`-''-/").___..--''"`-._
-- | `6_ 6 ) `-. ( ).`-.__.`)
-- | (_Y_.)' ._ ) `._ `. ``-..-'
-- | _..`--'_..-_/ /--'_.' ,'
-- | (il),-'' (li),' ((!.-'
--
James Edward Gray II

2004-05-18, 11:30 pm

On May 18, 2004, at 9:14 PM, Jason Dusek wrote:

> Hi,
>
> Is there an easy way to get all the unique elements of an array? i.e.
> is there some module or function that does that sort of thing?


There are excellent modules to handle this, but it's also pretty simple
to roll your own in most cases:

sub unique { # see title of this message for usage
my @all = @_;
my %seen;
$seen{$_}++ foreach @all;
return keys %seen;
}

Hope that helps.

James

Randy W. Sims

2004-05-19, 12:30 am

On 5/18/2004 10:46 PM, James Edward Gray II wrote:

> On May 18, 2004, at 9:14 PM, Jason Dusek wrote:
>
>
>
> There are excellent modules to handle this, but it's also pretty simple
> to roll your own in most cases:
>
> sub unique { # see title of this message for usage
> my @all = @_;
> my %seen;
> $seen{$_}++ foreach @all;
> return keys %seen;
> }


or it can be made uglier:

sub uniq { return keys %{{ map { $_, 1 } @_ }} }

Isn't this in the faq? `perldoc -q faq`

Randy.


Randy W. Sims

2004-05-19, 12:30 am

On 5/18/2004 11:00 PM, Randy W. Sims wrote:
> sub uniq { return keys %{{ map { $_, 1 } @_ }} }


Sorry for the nice formatting, that should have been:

sub uniq{keys%{{map{$_,1}@_}}}


Jason Dusek

2004-05-19, 12:30 am

What modules handle this? I have been digging around in CPAN all day...
--
-- Jason Dusek ("`-''-/").___..--''"`-._
-- | `6_ 6 ) `-. ( ).`-.__.`)
-- | (_Y_.)' ._ ) `._ `. ``-..-'
-- | _..`--'_..-_/ /--'_.' ,'
-- | (il),-'' (li),' ((!.-'
--

James Edward Gray II wrote:

> On May 18, 2004, at 9:14 PM, Jason Dusek wrote:
>
i.e. is there some module or function that does that sort of thing?[color=darkred]
>
>
>
> There are excellent modules to handle this, but it's also pretty

simple to roll your own in most cases:
>
> sub unique { # see title of this message for usage
> my @all = @_;
> my %seen;
> $seen{$_}++ foreach @all;
> return keys %seen;
> }
>
> Hope that helps.
>
> James
>
>

James Edward Gray II

2004-05-19, 12:30 am

On May 18, 2004, at 10:12 PM, Jason Dusek wrote:

> What modules handle this? I have been digging around in CPAN all day...


Searching the CPAN for "array unique", the first match is the super
Tie::Array::Unique.

http://search.cpan.org/~pinyan/Tie-...-0.01/Unique.pm

Hope that helps.

James

Jeff 'Japhy' Pinyan

2004-05-19, 12:30 am

On May 18, James Edward Gray II said:

>On May 18, 2004, at 10:12 PM, Jason Dusek wrote:
>
>
>Searching the CPAN for "array unique", the first match is the super
> Tie::Array::Unique.
>
>http://search.cpan.org/~pinyan/Tie-...-0.01/Unique.pm


Yes, I agree, it's super . (I'm the author.)

All you need to do is drop in:

use Tie::Array::Unique;
tie my(@array), 'Tie::Array::Unique';

into your code, and @array will automatically be guaranteed to hold only
unique elements. You have to download and install the module, of course,
but that's a simple process.

--
Jeff "japhy" Pinyan japhy@pobox.com http://www.pobox.com/~japhy/
RPI Acacia brother #734 http://www.perlmonks.org/ http://www.cpan.org/
CPAN ID: PINYAN [Need a programmer? If you like my work, let me know.]
<stu> what does y/// stand for? <tenderpuss> why, yansliterate of course.

Ramprasad A Padmanabhan

2004-05-19, 1:30 am

On Wed, 2004-05-19 at 08:35, Randy W. Sims wrote:
> On 5/18/2004 11:00 PM, Randy W. Sims wrote:
>
> Sorry for the nice formatting, that should have been:
>
> sub uniq{keys%{{map{$_,1}@_}}}
>
>


Are u sure that works ?
I just wrote out a script didnot work for me

#!/usr/bin/perl

my @arr = qw(a b c d a b e f );
print join(" " , sort @arr) . "\n" . '#' x 50 . "\n";
print join(" " , sort (uniq (@arr))) . "\n";
exit 0;
sub uniq{keys%{{map{$_,1}@_}}}
__END__

The output I got was

a a b b c d e f
########################################
##########
a b c d a b e f



I dont think there is anything wrong with the function uniq, the
function works fine ( when I print within the function ). I think the
issue is with the return

Thanks
Rampra





Jeff 'Japhy' Pinyan

2004-05-19, 1:30 am

On May 19, Rampra A Padmanabhan said:

>#!/usr/bin/perl
>
>my @arr = qw(a b c d a b e f );
>print join(" " , sort @arr) . "\n" . '#' x 50 . "\n";
>print join(" " , sort (uniq (@arr))) . "\n";
>exit 0;
>sub uniq{keys%{{map{$_,1}@_}}}


Perl is not sorting the return values of the uniq() function, Perl is
using 'uniq' as the comparison function to sort(). This is *ALL* because
you have a space after the function name. If you did

sort(uniq(@arr))

or

sort +uniq(@arr)

you'd print the sorted unique values.

--
Jeff "japhy" Pinyan japhy@pobox.com http://www.pobox.com/~japhy/
RPI Acacia brother #734 http://www.perlmonks.org/ http://www.cpan.org/
CPAN ID: PINYAN [Need a programmer? If you like my work, let me know.]
<stu> what does y/// stand for? <tenderpuss> why, yansliterate of course.

Randy W. Sims

2004-05-19, 1:30 am

On 5/19/2004 12:30 AM, Rampra A Padmanabhan wrote:

> On Wed, 2004-05-19 at 08:35, Randy W. Sims wrote:
>
>
>
> Are u sure that works ?
> I just wrote out a script didnot work for me
>
> #!/usr/bin/perl
>
> my @arr = qw(a b c d a b e f );
> print join(" " , sort @arr) . "\n" . '#' x 50 . "\n";
> print join(" " , sort (uniq (@arr))) . "\n";
> exit 0;
> sub uniq{keys%{{map{$_,1}@_}}}
> __END__
>
> The output I got was
>
> a a b b c d e f
> ########################################
##########
> a b c d a b e f
>
>
>
> I dont think there is anything wrong with the function uniq, the
> function works fine ( when I print within the function ). I think the
> issue is with the return


use strict;
use warnings;

There is ambiguity in your call to the function; perl does not know it
is a function. Prefix the call with '&' or '+', and it will work. A
better solution might be to use temporaries to construct your list.

Randy.


Lrmk

2004-05-19, 4:30 am

here is a function to remove the duplicated elements
it treates the elements as strings
you can use this for numaric values after changing 'eq' to '=='

only problem of this code it significantly alter the order of the array


sub unique(@){
my(@source) = @_;
my @destination;

@source = sort(@source);

foreach (@source){
if (!($destination[$#destination] eq $_)){
$destination[++$#destination] = $_;
}
}
return @destination;
}



________________________________________

Rakhitha Karunarathne
Web Master
www.Ad-Man.tk - Free Unlimited Banner Rotators
________________________________________




----- Original Message -----
From: "Jason Dusek" <jdusek@cs.uiowa.edu>
To: <beginners@perl.org>
Sent: Wednesday, May 19, 2004 8:14 AM
Subject: @UNIQUE=unique(@REDUNDANT);


> Hi,
>
> Is there an easy way to get all the unique elements of an array? i.e. is
> there some module or function that does that sort of thing?
> --
> -- Jason Dusek ("`-''-/").___..--''"`-._
> -- | `6_ 6 ) `-. ( ).`-.__.`)
> -- | (_Y_.)' ._ ) `._ `. ``-..-'
> -- | _..`--'_..-_/ /--'_.' ,'
> -- | (il),-'' (li),' ((!.-'
> --
>
> --
> To unsubscribe, e-mail: beginners-unsubscribe@perl.org
> For additional commands, e-mail: beginners-help@perl.org
> <http://learn.perl.org/> <http://learn.perl.org/first-response>
>
>
>
>

Remo Sanges

2004-05-19, 5:30 am

On May 19, 2004, at 10:14 AM, Jason Dusek wrote:

> Is there an easy way to get all the unique elements of an array? i.e.
> is there some module or function that does that sort of thing?


It's a very common problem...
a simple solution is to use hash:

#!/usr/bin/perl
use strict;
use warnings;

my @array = qw(a s f d a s e c v b f f r e a a s d);
my %hash;
foreach my $el(@array) {
$hash{$el} ++;
}
foreach my $key (keys %hash) {
print $key."\t".$hash{$key}."\n" if $hash{$key} == 1;
}


Randy W. Sims

2004-05-19, 6:30 am

Jason Dusek wrote:
> Hi,
>
> Is there an easy way to get all the unique elements of an array? i.e. is
> there some module or function that does that sort of thing?


Hmm, none of the solutions so far have been stable. In other words all
the solutions so far modify the order of elements from the source array.
How would you implement a version of the function that produced an array
where the elements are in the same order and only the first of any
duplicates are kept?


( a b c d e f g h ) == stable_uniq( a b c d a b e f c g h )
Ramprasad A Padmanabhan

2004-05-19, 6:30 am

On Wed, 2004-05-19 at 14:28, Randy W. Sims wrote:
> Jason Dusek wrote:
>
> Hmm, none of the solutions so far have been stable. In other words all
> the solutions so far modify the order of elements from the source array.
> How would you implement a version of the function that produced an array
> where the elements are in the same order and only the first of any
> duplicates are kept?
>
>
> ( a b c d e f g h ) == stable_uniq( a b c d a b e f c g h )



No,
The solution given by some users , ( using no hash keys ) do maintain
order. But in practical sense , I never encountered a case where I
required the unique elements and also the order of an array

Ram




Bob Showalter

2004-05-19, 9:30 am

Randy W. Sims wrote:
> How would you implement a version of the function that
> produced an array where the elements are in the same order and only
> the first of any duplicates are kept?


@uniq = do { my %seen; grep !$seen{$_}++, @arr };

Or, if you want a function:

sub uniq { my %seen; grep !$seen{$_}++, @_ }

(But Tie::Array is much more flexible in handling the definition of
"duplicate")
Jeff 'Japhy' Pinyan

2004-05-19, 10:31 am

On May 19, Randy W. Sims said:

>Hmm, none of the solutions so far have been stable. In other words all
>the solutions so far modify the order of elements from the source array.
>How would you implement a version of the function that produced an array
>where the elements are in the same order and only the first of any
>duplicates are kept?
>
>( a b c d e f g h ) == stable_uniq( a b c d a b e f c g h )


You've been shown how to do it with grep(), but Tie::Array::Unique is
stable, or at least it has been in all my tests.

--
Jeff "japhy" Pinyan japhy@pobox.com http://www.pobox.com/~japhy/
RPI Acacia brother #734 http://www.perlmonks.org/ http://www.cpan.org/
CPAN ID: PINYAN [Need a programmer? If you like my work, let me know.]
<stu> what does y/// stand for? <tenderpuss> why, yansliterate of course.

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com