我正在学习 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
在哈希上使用无需编写循环来迭代哈希中的每个项目。
这是我正在使用的结构的一些示例数据。在分配 URI 之前,我想检查是否有任何项目已经具有该 uri 值。例如,我想分配ww1.example.com
给 item v2rbz1568
,但前提是没有其他项目的 uri 值为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
至少有两个选择:
- 您(仅)拥有您在问题中设想的数据结构。然后,每次你想找到匹配项时,你都必须遍历整个“列表”。不过,您不必编写循环,您可以使用该
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";
}
- 您可以在哈希中管理一个单独的索引,以便可以进行快速查找。索引意味着您有一个单独的哈希映射 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";
在第二种情况下,每次在“列表”中添加/更新/删除 URI 时,您都必须手动更新索引:
$entries{"v84x9v8b9"} = { uri => "ww49", ... };
$index{"ww49"} = "v84x9v8b9";