【问题标题】:Perl: Is this a correct way of creating an unique array?Perl:这是创建唯一数组的正确方法吗?
【发布时间】:2012-06-24 10:24:53
【问题描述】:

我正在尝试创建一个唯一的数组,而不管其原始顺序如何,并且不使用任何模块,这就是我迄今为止提出的:

my @arr = qw(b a a c d g e f);
my %hash;
@hash{@arr}=();
say keys %hash;

【问题讨论】:

    标签: arrays perl perl-data-structures perl-hash


    【解决方案1】:

    是的。由于哈希键是唯一的,因此这是一种惯用的方法。完成同一件事的方法有很多。

    你也可以使用一个模块,比如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{$_}++ } @_;
    }
    

    【讨论】:

    • 谢谢,我只是想,与其将 1 或 undef 分配给它的值,我们可以像这样为每个键赋予其关联的数组位置:@hash{@arr}=(0..$#arr); 然后通过交换 @987654331 中的键和值@我们可以根据原始顺序检索值,对吗?
    • 是的,您可以使用my @arr = sort { $hash{$a} <=> $hash{$b} } keys %hash。但是,上面描述的uniq 子更可取,因为排序只是额外的处理。
    • @loldop 您可以将哈希引用与keys 函数一起使用。不确定需要哪个 perl 版本。
    • @TLP,我的旧 perl 5.12.4 做不到:\
    【解决方案2】:

    是的,您使用了正确的方法,但还有许多其他方法可以创建唯一数组。

    请参阅 perlfaq4:How can I remove duplicate elements from a list or array? 了解更多详情。

    【讨论】:

      【解决方案3】:

      一个没有排序的唯一数组,也就是一个集合。我知道你说“没有模块”(为什么?!)。但如果你改变主意,试试Set::ObjectSet::Scalar

      【讨论】:

      • 谢谢,因为我的目的是理解概念而不是解决问题,否则我使用模块没有问题。
      猜你喜欢
      • 2011-01-31
      • 1970-01-01
      • 1970-01-01
      • 2016-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-24
      相关资源
      最近更新 更多