2016-05-06 37 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; 
相關問題