# perldoc > dup

---
type: CommandReference
command: perlfaq
mode: perldoc
section: 4,5
source: perldoc
---

## Quick Reference

- `my %hash = map { $_, 1 } @array; my @unique = keys %hash;` — remove duplicates, order not preserved
- `use List::MoreUtils qw(uniq); my @unique = uniq(@list);` — preserve order, returns unique elements (list) or count (scalar)
- `my %seen; my @unique = grep { !$seen{$_}++ } @array;` — remove duplicates preserving order using a hash
- `open my $log, '>>', '/foo/logfile'; open STDERR, '>&', $log;` — dup a filehandle via copy
- `open my $mhcontext, "<&=$fd";` — dup a filehandle via alias (like `fdopen`)

## Name

Perl FAQ entries on removing duplicate elements from a list or array and duping a filehandle.

## Removing Duplicates (from perlfaq4)

(contributed by brian d foy)

Use a hash. When you think "unique" or "duplicated", think "hash keys".

If you don't care about the order of the elements, create the hash then extract the keys:

perl
my %hash   = map { $_, 1 } @array;
# or a hash slice: @hash{ @array } = ();
# or a foreach: $hash{$_} = 1 foreach ( @array );

my @unique = keys %hash;
If you want a module, use `uniq` from [List::MoreUtils](https://perldoc.perl.org/List::MoreUtils). In list context, returns unique elements preserving order; in scalar context, returns the number of unique elements:

perl
use List::MoreUtils qw(uniq);

my @unique = uniq( 1, 2, 3, 4, 4, 5, 6, 5, 7 ); # 1,2,3,4,5,6,7
my $unique = uniq( 1, 2, 3, 4, 4, 5, 6, 5, 7 ); # 7
You can also iterate and skip seen elements using a hash:

perl
my @unique = ();
my %seen   = ();

foreach my $elem ( @array ) {
    next if $seen{ $elem }++;
    push @unique, $elem;
}
A more concise `grep` version:

perl
my %seen = ();
my @unique = grep { ! $seen{ $_ }++ } @array;
## Duping Filehandles (from perlfaq5)

To dup a filehandle, use `open` with the `>&` or `<&=` operators. Example:

perl
open my $log, '>>', '/foo/logfile';
open STDERR, '>&', $log;
Or with a numeric file descriptor:

perl
my $fd = $ENV{MHCONTEXTFD};
open $mhcontext, "<&=$fd";  # like fdopen(3)
Note: `<&STDIN` makes a copy, but `<&=STDIN` makes an alias. Closing an aliased handle makes all aliases inaccessible; this is not true for a copy.

Error checking is left as an exercise for the reader.