我正在将两个制表符分隔的文件读成两个哈希,文件如下所示:
apple fruit
pear fruit
carrot vegetable
potato vegetable
peach fruit
和
apple 23
pear 34
carrot 12
potato 45
peach 12
我想只拿起蔬菜来获取他们的数字。有没有比通过周期更聪明的方式来做到这一点? 如果我想创建两个新的哈希%fruit和%vegetable,我真的必须这样做:
foreach (keys %kinds_hash) {
if ($kinds_hash{$_} =~ "vegetable") {
$vegetable{$_} = $numbers_hash{$_};
} elsif ($kinds_hash{$_} =~ "fruit") {
$fruit{$_} = $numbers_hash{$_};
}
}
答案 0 :(得分:0)
迭代所有值都没有错。
但是,如果您经常这样做,那么创建一个包含基于类型的名称数组的新数据结构可能会很有用。
use strict;
use warnings;
# Data in Paragraph mode
local $/ = '';
my %counts = split ' ', <DATA>;
my %types = split ' ', <DATA>;
# Create a structure that puts each type into an array
my %group_by_type;
while (my ($name, $type) = each %types) {
push @{$group_by_type{$type}}, $name
}
# Show all Veges
for my $fruit (@{$group_by_type{vegetable}}) {
print "$fruit $counts{$fruit}\n";
}
__DATA__
apple 23
pear 34
carrot 12
potato 45
peach 12
apple fruit
pear fruit
carrot vegetable
potato vegetable
peach fruit
输出:
carrot 12
potato 45
要了解有关阵列哈希和其他数据结构的更多信息,请查看perldsc
- Perl Data Structures Cookbook
答案 1 :(得分:0)
您应该构建数据,以便尽可能简化您想要访问它的所有方式。
您想要访问vegetable
类别中的所有项目以及所有这些项目的数字。为了简单起见,我将构建两个哈希 - 一个将项目的名称与其编号和类别相关联,另一个将类别与每个类别中的所有名称相关联。
此代码就是这样做的,并使用Data::Dump
向您展示已构建的内容。
use strict;
use warnings;
use autodie;
my %items;
my %categories;
open my $fh, '<', 'numbers.tabsep';
while (<$fh>) {
next unless /\S/;
chomp;
my ($name, $number) = split /\t/;
$items{$name}[0] = $number;
}
open $fh, '<', 'categories.tabsep';
while (<$fh>) {
next unless /\S/;
chomp;
my ($name, $cat) = split /\t/;
$items{$name}[1] = $cat;
push @{ $categories{$cat} }, $name;
}
use Data::Dump;
dd \%items;
dd \%categories;
<强>输出强>
{
apple => [23, "fruit"],
carrot => [12, "vegetable"],
peach => [12, "fruit"],
pear => [34, "fruit"],
potato => [45, "vegetable"],
}
{
fruit => ["apple", "pear", "peach"],
vegetable => ["carrot", "potato"],
}
现在,回答问题&#34;我想只拿起蔬菜并获取他们的数字&#34; 我们只是遍历{{1}的vegetable
元素哈希,并使用%categories
哈希来确定它们的数字。喜欢这个
%items
<强>输出强>
for my $item (@{ $categories{vegetable} }) {
printf "%s %d\n", $item, $items{$item}[0];
}
工具已成功完成
答案 2 :(得分:0)
您可以创建哈希哈希,只需一个嵌套数据结构,其中内部键将是您的类别,值将是另一个哈希,其键将是类型,值是数字。
以下程序执行此操作:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my %data;
open my $fh_one, '<', 'file1';
while(<$fh_one>) {
next unless /\S+/;
chomp;
my ($type, $category) = split /\t/;
$data{$category}{$type} = undef;
}
close($fh_one);
open my $fh_two, '<', 'file2';
OUTER: while(<$fh_two>) {
next unless /\S+/;
chomp;
my ($type, $number) = split /\t/;
for my $category (keys %data) {
for my $item (keys %{ $data{$category} }) {
$data{$category}{$item} = $number and next OUTER if $item eq $type;
}
}
}
close($fh_two);
#print Dumper \%data;
while (my ($type, $number) = each $data{'vegetable'}) {
print "$type $number\n";
}
如果取消注释print Dumper \%data;
,您将看到嵌套的数据结构。它将如下所示:
$VAR1 = {
'fruit' => {
'peach' => '12',
'apple' => '23',
'pear' => '34'
},
'vegetable' => {
'carrot' => '12',
'potato' => '45'
}
};
上述程序的输出是:
carrot 12
potato 45