2016-05-06 40 views
0

在Perl中是否有一个很好的一行,可以让你从一个字符串创建一个唯一值的数组?什么是从字符串创建唯一数组值的最佳方式?

$str = "bob-2-4 asdfasdfasdf bob-2-4 asdfasdf bob-3-1"; 
my @unique = $str =~ m/(bob-\d-\d)/g; 
# array is now "bob-2-4, bob-2-4, bob-3-1" 

但是我希望唯一的数组只包含“bob-2-4,bob-3-1”。

+0

'perl -E'say for grep {/^bob- \ d + - \ d + $/&&!$ s {$ _} ++} split“”,shift''bob-2-4 asdfasdfasdf bob- 2-4 asdfasdf bob-3-1'' – Borodin

+0

或者如果你想要一个数组(不是单行),那么'my%s; my @unique = grep {/^bob- \ d + - \ d + $/&&!%s {$ _} ++} split'',$ str;' – Borodin

回答

1

如果你在谈论唯一身份证,那么这项工作的工具就是一个散列。

你可以这样做:

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

my $str = "bob-2-4 asdfasdfasdf bob-2-4 asdfasdf bob-3-1"; 
my %unique = map { $_ => 1 } $str =~ m/(bob-\d-\d)/g; 
print keys %unique; 

作为一个衬垫,直入你的数组,你可以:

my @unique = keys %{{map { $_ => 1 } $str =~ m/(bob-\d-\d)/g}}; 

这大约做同样的事情 - 用map构建乱码,然后keys来提取唯一值。注 - keys不返回已定义的订单。

如果排序是非常重要的,你也可以使用grep,但你仍然需要一个散列:

my $str = "bob-2-4 asdfasdfasdf bob-2-4 asdfasdf bob-3-1"; 
my %seen; 
my @unique = grep { not $seen{$_}++ } $str =~ m/(bob-\d-\d)/g; 
print @unique; 
+1

您也可以使用List :: MoreUtils中的'uniq',它做同样的事情,但在语法上更干净。 –

+1

没有看到使用不保留顺序的解决方案的重点,尤其是因为它们创建了所有唯一值的副本。 – ikegami

+0

哦对。谢谢。 – user740521

5

不含模块:

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

凭借常用模块:

use List::MoreUtils qw(uniq); 

用法:

my $str = "bob-2-4 asdfasdfasdf bob-2-4 asdfasdf bob-3-1"; 
my @unique = uniq $str =~ m/(bob-\d-\d)/g; 
say for @unique; 
相关问题