2016-05-06 5 views
0

文字列から一意の値の配列を作成するための素晴らしいlinerが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 'grep {/^bob- \ d + - \ d + $/&&!$ s {$ _} ++} split" "、シフト" bob-2-4 asdfasdfasdf bob- 2-4 asdfasdf bob-3-1'' – Borodin

+0

または(1行ではなく)配列を使用する場合は、 'my%s; $ str; ' – Borodin

答えて

1

ユニークについては、ジョブのツールはハッシュです。 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を使用することができますが、あなたはまだハッシュ必要があります:一般的に使用されるモジュールで

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

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

モジュールなしを

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; 
関連する問題