Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Array::Unique(3)      User Contributed Perl Documentation     Array::Unique(3)

       Array::Unique - Tie-able	array that allows only unique values

	use Array::Unique;
	tie @a,	'Array::Unique';

	Now use	@a as a	regular	array.

       This package lets you create an array which will	allow only one
       occurrence of any value.

       In other	words no matter	how many times you put in 42 it	will keep only
       the first occurrence and	the rest will be dropped.

       You use the module via tie and once you tied your array to this module
       it will behave correctly.

       Uniqueness is checked with the 'eq' operator so among other things it
       is case sensitive.

       As a side effect	the module does	not allow undef	as a value in the

	use Array::Unique;
	tie @a,	'Array::Unique';

	@a = qw(a b c a	d e f);
	push @a, qw(x b	z);
	print "@a\n";	       # a b c d e f x z

       When you	are collecting a list of items and you want to make sure there
       is only one occurrence of each item, you	have several option:

       1) using	an array and extracting	the unique elements later
	   You might use a regular array to hold this unique set of values and
	   either remove duplicates on each update by that keeping the array
	   always unique or remove duplicates just before you want to use the
	   uniqueness feature of the array. In either case you might run a
	   function you	call @a	= unique_value(@a);

	   The problem with this approach is that you have to implement	the
	   unique_value	function (see later) AND you have to make sure you
	   don't forget	to call	it. I would say	don't rely on remembering

	   There is good discussion about it in	the 1st	edition	of the Perl
	   Cookbook of O'Reilly. I have	copied the solutions here, you can see
	   further discussion in the book.

	   Extracting Unique Elements from a List (Section 4.6 in the Perl
	   Cookbook 1st	ed.)

	   # Straightforward

	    %seen = ();
	    @uniq = ();
	    foreach $item (@list) [
		unless ($seen{$item}) {
		  # if we get here we have not seen it before
		  $seen{$item} = 1;
		  push (@uniq, $item);

	   # Faster

	    %seen = ();
	    foreach $item (@list) {
	      push(@uniq, $item) unless	$seen{$item}++;

	   # Faster but	different

	    foreach $item (@list) {
	    @uniq = keys %seen;

	    # Faster and even more different
	    @uniq = grep {! $seen{$_}++} @list;

       2) using	a hash
	   Some	people use the keys of a hash to keep the items	and put	an
	   arbitrary value as the values of the	hash:

	   To build such a list:

	    %unique = map { $_ => 1 } qw( one two one two three	four! );

	   To print it:

	    print join ", ", sort keys %unique;

	   To add values to it:

	    $unique{$_}=1 foreach qw( one after	the nine oh nine );

	   To remove values:

	    delete @unique{ qw(oh nine)	};

	   To check if a value is there:

	    $unique{ $value };	      #	which is why I like to use "1" as my value

	   (thanks to Gaal Yahas for the above examples)

	   There are three drawbacks I see:

	   1) You type more.
	   2) Your reader might	not understand at first	why did	you use	hash
	   and what will be the	values.
	   3) You lose the order.

	   Usually non of them is critical but when I saw this the 10th	time
	   in a	code I had to understand with 0	documentation I	got

       3) using	Array::Unique
	   So I	decided	to write this module because I got frustrated by my
	   lack	of understanding what's	going on in that code I	mentioned.

	   In addition I thought it might be interesting to write this and
	   then	benchmark it.

	   Additionally	it is nice to have your	name displayed in bright
	   lights all over CPAN	... or at least	in a module.

	   Array::Unique lets you tie an array to hmmm,	itself (?)  and	makes
	   sure	the values of the array	are always unique.

	   Since writing this I	am not sure if I really	recommend its usage.
	   I would say stick with the hash version and document	that the
	   variable is aggregating a unique list of values.

       4) Using	real SET
	   There are modules on	CPAN that let you create and maintain SETs.  I
	   have	not checked any	of those but I guess they just as much of an
	   overkill for	this functionality as Unique::Array.

	use Array::Unique;
	tie @a,	'Array::Unique';

	@c = @a	= qw(a b c a d e f b);

	@c will	contain	the same as @a AND two undefs at the end because
	@c you get the same length as the right	most list.


       Change size of the array	Elements with false values ('',	'0', 0)

	  splice @a;
	  splice @a,  3;
	  splice @a, -3;
	  splice @a,  3,  5;
	  splice @a,  3, -5;
	  splice @a, -3,  5;
	  splice @a, -3, -5;
	  splice @a,  ?,  ?, @b;

       Benchmark speed

       Add faster functions that don't check uniqueness	so if I	know part of
       the data	that comes from	a unique source	then I can speed up the
       process,	In short shoot myself in the leg.

       Enable optional compare with other functions

       Write even better implementations.

       Gabor Szabo <>

       Copyright (C) 2002-2008 Gabor Szabo <> All rights

       You may distribute under	the terms of either the	GNU General Public
       License or the Artistic License,	as specified in	the Perl README	file.

       No WARRANTY whatsoever.

	Thanks for suggestions and bug reports to
	Szabo Balazs (dLux)
	Shlomo Yona
	Gaal Yahas
	Jeff 'japhy' Pinyan
	Werner Weichselberger

       Version:	0.08

       Date:	2008 June 04

perl v5.32.0			  2008-06-04		      Array::Unique(3)


Want to link to this manual page? Use this URL:

home | help