我有一个哈希/数组结构,但是有些哈希键的情况并不相同。
我想知道是否有办法处理这种情况,而无需手动检查每个哈希的密钥。
在下面的示例中,我希望打印所有ID / iD / id / Id字段。
use warnings;
use strict;
my $Hash = {
Server => [
{
Id=>123
},
{
iD=>456
},
{
ID=>789
}
]
};
for (@{$Hash->{Server}}){
print "$_->{ID}\n"
#This is the problematic part
}
perl版本:v5.10.0
这些数据是从其他地方收到的,必须保持相同的情况,上面的例子是最小的,我不能简单地将它们全部更改为相同的情况。
需要更多信息让我知道。
答案 0 :(得分:5)
嗯,这取决于你的信息来源。这看起来像你已经解析了一些东西,所以可能有更好的解决方案。
然而,根据我们在这里所做的事情,我是这样做的:
for my $entry (@{$Hash->{Server}}){
#grep, find first match. Dupes discarded.
my ( $key ) = grep { /^id$/i } keys %$entry;
print "$key => ",$entry -> {$key},"\n";
}
这可以通过grep
使用i
正则表达式来解决keys
上不区分大小写的问题,并抓住先出现的内容。因此,如果您有/id/i
的多个匹配项,那么它将是随机的。 (sort
可以帮助解决这个问题)
鉴于你正在与XML
合作,我可能会稍微回溯一下,抛弃XML::Simple
而是这样做:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig -> new ( twig_handlers => { '_all_' => sub { $_ -> lc_attnames }} );
$twig -> parse ( \*DATA );
print "XML looks like:\n";
$twig -> set_pretty_print ( 'indented_a');
$twig -> print;
print "Output:\n";
foreach my $server ( $twig -> get_xpath('//Server') ) {
print $server -> att('id'),"\n";
}
__DATA__
<XML>
<Server ID="123" />
<Server Id="456" />
<Server id="789" />
</XML>
或者你可以:
foreach my $server ( $twig -> get_xpath('//Server') ) {
$server -> lc_attnames;
print $server -> att('id'),"\n";
}
代替在树枝处理程序中执行此操作。第一个答案将修复&#39;您的所有XML都具有小写属性,这可能不是您想要的。但是,它可能对其他场景有用,这就是为什么我给出了两个例子。
答案 1 :(得分:1)
没有内置的方法可以做到这一点。您可以做的是使用List::Util's first
至少获得更少的检查,然后仍然尝试直到一个适合每个键。
use strict;
use warnings;
use feature 'say';
use List::Util 'first';
my $Hash = {
Server => [
{
Id => 123
},
{
iD => 456
},
{
ID => 789
}
]
};
foreach my $thing ( @{ $Hash->{Server} } ) {
# this returns the first match in the list, like grep
# so we need to use it here to return the actual value
say $thing->{ first { $thing->{$_} } qw/id ID iD Id/ };
}
如果数据结构中有很多其他键,这比查看所有键都要便宜,因为你最多可以查找所有可能的 id 键加一个,最多两个
如果您想要自动生成可能的键列表,并且可以任意混合使用大写和小写字母,请查看this answer。
答案 2 :(得分:-1)
我建议你使用正则表达式来忽略使用i
标志的密钥大小。
for my $item ( @ { $Hash->{Server} }) {
for(keys %{$item}) {
print $item -> {$_},"\n" if /^ID$/i;
}
}