我有一个包含以下信息的文件
1:2=14
3:4=15
2:1=16
4:3=17
我想创建一个哈希处理密钥{1:2}
与密钥{2:1}
$hash{1:2} = $hash{2:1}
所以当我打印$hash{1:2}
或$hash{2:1}
中的所有元素时,它会同时给我14
和16
。这是一种简单的方法吗?
以下是我计划创建哈希
的密钥for ( my $i = 0; $i <=$#file ; $i++) {
my $line = $file[$i];
my @key = split ("=",$line);
my $hash{$key[0]} = $key[1];
}
答案 0 :(得分:2)
没有内置的方法可以做到这一点。如果您的键遵循相同的模式,您可以将其包装在一个函数中,然后计算适合您的算法的所有键并获取值。
my %hash = (
'1:2' => 14,
'3:4' => 15,
'2:1' => 16,
'4:3' => 17,
);
sub get_elements {
my ($key) = @_;
return $hash{$key}, $hash{reverse $key}; # or $key =~ s/(\d+):(\d+)/$2:$1/r
}
print join ' ', get_elements('1:2');
这使用字符串reverse
,显然只有在键的部分只有一位数时才有效。如果您的数字大于9,则必须拆分字符串并重新组合,或使用替换来切换它们。我的示例使用/r
修饰符,该修饰符需要Perl 5.14 or higher。
如果您想在阅读自动处理文件时构建数据结构,您也可以这样做。使用数组引用而不是哈希中的简单值,并将相同的引用分配给您想要相等的所有键。
use strict;
use warnings;
use feature 'say';
use Data::Dumper;
my %hash;
while (my $line = <DATA>) {
chomp $line;
my ($key, $value) = split /=/, $line;
my ($left, $right) = split /:/, $key;
# $hash{$key} //= ( $hash{"$right:$left"} // [] ); # needs 5.10
$hash{$key} = ( $hash{"$right:$left"} || [] )
unless exists $hash{$key};
push @{ $hash{$key} }, $value;
}
say "@{ $hash{'1:2'} }";
say "@{ $hash{'2:1'} }";
print Dumper \%hash;
__DATA__
1:2=14
3:4=15
2:1=16
4:3=17
此代码的输出是
14 16
14 16
Data :: Dumper结构如下所示,它解释了键2:1
和1:2
都指向相同的数组引用。这意味着如果你将push
另一个值放入其中一个中,它也会在另一个中结束,因为它们实际上是相同的。
$VAR1 = {
'4:3' => [
'15',
'17'
],
'3:4' => $VAR1->{'4:3'},
'2:1' => [
'14',
'16'
],
'1:2' => $VAR1->{'2:1'}
};
唯一的缺点是你无法获得元素的顺序。此数据结构失去了1:2
最初具有值14
且2:1
具有16
的知识。如果您希望2:1
输出16 14
,则无效。