配列の代わりにハッシュでPerl grepを使用する方法は?

配列の代わりにハッシュでPerl grepを使用する方法は?

私はパールを学んでいます。grep配列で使用できましたが、構文は次のように非常に簡単です。はい:

use strict; use warnings;

my @names = qw(Foo Bar Baz);
my $visitor = <STDIN>;
chomp $visitor;
if (grep { $visitor eq $_ } @names) {
   print "Visitor $visitor is in the guest list\n";
} else {
   print "Visitor $visitor is NOT in the guest list\n";
}

grepしかし、ハッシュで動作するのと同じように単純な方法があるかどうか疑問に思います。ハッシュの各項目を繰り返すためにループを作成する必要はありません。

以下は、私が使用している構造に関するいくつかのサンプルデータです。 URIを割り当てる前に、アイテムにすでに対応するURI値があることを確認したいと思います。例えば、ww1.example.comitemに割り当てたいがv2rbz1568uri値を持つ他の項目がない場合にのみ可能ですww1.example.com。 Perlでこれを効率的に実行するにはどうすればよいですか?

{
    "0y7vfr1234": {
        "username": "[email protected]",
        "password": "some-random-password123",
        "uri": "ww1.example.com",
        "index": 14
    },
    "v2rbz1568": {
        "username": "[email protected]",
        "password": "some-random-password125",
        "uri": "ww3.example.com",
        "index": 29
    },
    "0zjk1156": {
        "username": "[email protected]",
        "password": "some-random-password124",
        "uri": "ww2.example.com",
        "index": 38
    }
}

私はLinuxでPerl 5バージョン30を使用しています。

ベストアンサー1

少なくとも2つのオプションがあります。

  1. あなたはあなたの質問から想定したデータ構造のみを持っています。その後、一致するものを探したいときはいつでも「リスト全体」を繰り返す必要があります。ただし、ループを作成する必要はなく、次のmap関数を使用できます。
use strict; use warnings;
my %entries = (
    '0y7vfr1234' => {
        'username' => '[email protected]',
        'password' => 'some-random-password123',
        'uri' => 'ww1.example.com',
        'index' => 14
    },
    'v2rbz1568' => {
        'username' => '[email protected]',
        'password' => 'some-random-password125',
        'uri' => 'ww3.example.com',
        'index' => 29
    }
);
my $uri = <STDIN>;
chomp $uri;
if (grep { $uri eq $_ } map { $_->{'uri'} } values %entries) {
   print "URI $uri is in the list\n";
} else {
   print "URI $uri is NOT in the list\n";
}
  1. クイックルックアップを可能にするために、ハッシュに別々のインデックスを管理できます。索引付けとは、URI を項目の実際のハッシュにマップする別のハッシュがあることを意味します。
use strict; use warnings;
my %entries = (
    '0y7vfr1234' => {
        'username' => '[email protected]',
        'password' => 'some-random-password123',
        'uri' => 'ww1.example.com',
        'index' => 14
    },
    'v2rbz1568' => {
        'username' => '[email protected]',
        'password' => 'some-random-password125',
        'uri' => 'ww3.example.com',
        'index' => 29
    }
);
my %index = map { $entries{"uri"} => $_ } keys %entries;

my $uri = <STDIN>;
chomp $uri;
my $item = $index{$uri};
if (defined($item)) {
   print "URI $uri is in the list\n";
} else {
   print "URI $uri is NOT in the list\n";
}

$itemハッシュが存在することを確認するだけでなく、ハッシュにすでに存在する項目にアクセスしたい場合は、検索結果を直接取得できるので便利です。print "Index: ",$entries{$item}->{'index'},"\n";

2番目のケースでは、URLが「リスト」に追加/更新/削除されるたびにインデックスを手動で更新する必要があります。

$entries{"v84x9v8b9"} = { uri => "ww49", ... };
$index{"ww49"} = "v84x9v8b9";

おすすめ記事