perl - 如何在perl中忽略哈希的键序列
问题描述
我有一个包含如下信息的文件
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];
}
解决方案
没有内置的方法可以做到这一点。如果您的键遵循相同的模式,您可以将其包装在一个函数中,然后计算适合您的算法的所有键并获取值。
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');
这使用 string reverse
,并且显然仅在密钥的部分只有一位时才有效。如果你可以有大于 9 的数字,你将不得不拆分字符串并重新组合它,或者使用替换来切换它们。我的示例使用了/r
修饰符,它需要Perl 5.14 或更高版本。
但是,如果您想在读取自动处理此问题的文件时构建数据结构,您也可以这样做。使用数组引用而不是哈希中的简单值,并将相同的引用分配给您希望相等的所有键。
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
推荐阅读
- flutter - 将 Whatsapp 业务 API 与 Flutter 应用程序集成
- python - python新手,刚刚遇到一个新错误:pygame.error: video system not initialized
- postgresql - 通过 pgAdmin 的“字符变化”和“字符变化 []”之间的 PostgreSQL 区别
- javascript - react native 中的嵌套列表组件
- excel - 如何在excel中将同一组中的表格中的损益组合在一起?
- javascript - TypeError:无法读取我的 api 中未定义的属性“地址”
- python - 如何从给定的索引数组中弹出列表中的元素?
- python - 如何在 bigquery 中插入一行 DATE 类型的列
- ruby - 测试 ruby 模块类方法不起作用
- python - 在 Python 中从网页中检索信息?