Perl
如何在雜湊而不是數組上使用 Perl grep?
我正在學習 Perl。我已經能夠
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
在 hash 上使用而無需編寫循環來遍歷 hash 中的每個項目。這是我正在使用的結構的一些範例數據。在分配 URI 之前,我想檢查是否有任何項目已經具有該 uri 值。例如,我想分配
ww1.example.com
給 itemv2rbz1568
,但前提是沒有其他項目的 uri 值為ww1.example.com
。我怎樣才能在 Perl 中有效地做到這一點?{ "0y7vfr1234": { "username": "user1@example.com", "password": "some-random-password123", "uri": "ww1.example.com", "index": 14 }, "v2rbz1568": { "username": "user3@example.com", "password": "some-random-password125", "uri": "ww3.example.com", "index": 29 }, "0zjk1156": { "username": "user2@example.com", "password": "some-random-password124", "uri": "ww2.example.com", "index": 38 } }
我在 Linux 上使用 perl 5,版本 30。
至少有兩種選擇:
- 您(僅)擁有您在問題中設想的資料結構。然後,每次要查找匹配項時,您都必須遍歷整個“列表”。您不必編寫循環,您可以使用該
map
函式:use strict; use warnings; my %entries = ( '0y7vfr1234' => { 'username' => 'user1@example.com', 'password' => 'some-random-password123', 'uri' => 'ww1.example.com', 'index' => 14 }, 'v2rbz1568' => { 'username' => 'user3@example.com', '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"; }
- 您在散列中管理一個單獨的索引,以便您可以進行快速查找。索引意味著您有一個單獨的雜湊映射 URI 到實際雜湊的項目:
use strict; use warnings; my %entries = ( '0y7vfr1234' => { 'username' => 'user1@example.com', 'password' => 'some-random-password123', 'uri' => 'ww1.example.com', 'index' => 14 }, 'v2rbz1568' => { 'username' => 'user3@example.com', '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";
在第二種情況下,每次在“列表”中添加/更新/刪除 URI 時,您都必須手動更新索引:
$entries{"v84x9v8b9"} = { uri => "ww49", ... }; $index{"ww49"} = "v84x9v8b9";