2012-06-22 42 views

回答

6

是。由于散列键是唯一的,所以这是一种惯用的方法。完成同样事情的方法很多。

你也可以使用一个模块,如List::MoreUtils

use strict; 
use warnings; 

use List::MoreUtils qw(uniq); 
print join ":", uniq qw(a a a b b c d); 

输出:

a:b:c:d 

有些不同的方式重复数据删除:

my @arr = keys { map { $_ => 1 } qw(b a a c d g e f) }; 

大括号创建匿名散列为keys,map语句创建一个键/值对列表。


my @arr = dedupe(qw(a a b c d d e)); 

sub dedupe { 
    my %hash = map { $_ => 1 } @_; 
    return keys %hash; 
} 

同样的事情,但在子程序的形式,分成两行。请注意,这两个列表将以半随机顺序排列,因为哈希是无序的。

List::MoreUtils使用的子程序同样简单,也许是可取的,因为它将保留参数的顺序。不过,它仍然使用散列。

sub uniq { 
    my %seen =(); 
    grep { not $seen{$_}++ } @_; 
} 
+0

谢谢,我只是想,而不是分配1或'undef'到它的值,我们可以给每个键的相关数组位置像这样:'@hash {@arr } =(0 .. $#arr);'然后通过交换'%hash'中的键和值,我们可以根据它们的原始顺序检索这些值,我是否正确? – bolbol

+2

是的,你可以做'my @arr = sort {$ hash {$ a} <=> $ hash {$ b}} keys%hash'。但是,上面描述的'uniq'子是最好的,因为排序只是额外的处理。 – TLP

+0

@TLP ok,但是'HASH-REF'键如何在你的例子中工作? – gaussblurinc

1

一个独特的阵列没有订购a.k.a.一套。我知道你说'没有模块'(为什么?!)。但是如果你改变了主意,试试Set::ObjectSet::Scalar

+0

谢谢,因为我的意图是理解概念,而不是解决问题,否则我没有使用模块的问题。 – bolbol

相关问题