我知道已经讨论了该主题,但是其他帖子通常具有静态哈希和数组,并且没有显示如何加载哈希和数组。我正在尝试处理音乐库。我有一个带有专辑名称的哈希和一个包含曲目号,歌曲标题和艺术家的哈希数组。这是从iTunes生成的XML文件加载的。
the pared down code follows:
use strict;
use warnings;
use utf8;
use feature 'unicode_strings';
use feature qw( say );
use XML::LibXML qw( );
use URI::Escape;
my $source = "Library.xml";
binmode STDOUT, ":utf8";
# load the xml doc
my $doc = XML::LibXML->load_xml( location => $source )
or warn $! ? "Error loading XML file: $source $!"
: "Exit status $?";
my %hCompilations;
my %track;
# extract xml fields
my @album_nodes = $doc->findnodes('/plist/dict/dict/dict');
for my $album_idx (0..$#album_nodes) {
my $album_node = $album_nodes[$album_idx];
my $trackName = $album_node->findvalue('key[text()="Name"]/following-sibling::*[position()=1]');
my $artist = $album_node->findvalue('key[text()="Artist"]/following-sibling::*[position()=1]');
my $album = $album_node->findvalue('key[text()="Album"]/following-sibling::*[position()=1]');
my $compilation = $album_node->exists('key[text()="Compilation"]');
# I only want compilations
if( ! $compilation ) { next; }
%track = (
trackName => $trackName,
trackArtist => $artist,
);
push @{$hCompilations{$album}} , %track;
}
#loop through each album access the album name field and get what should be the array of tracks
foreach my $albumName ( sort keys %hCompilations ) {
print "$albumName\n";
my @trackRecs = @{$hCompilations{$albumName}};
# how do I loop through the trackrecs?
}
此行没有按照您的想法进行:
push @{$hCompilations{$album}} , %track;
这会将您的哈希解包为键/值对的列表,并将每个散列分别推入数组。您想要的是将对哈希的引用推到数组上。
您可以通过创建哈希的新副本来做到这一点:
push @{$hCompilations{$album}} , { %track };
但是这会带来不必要的哈希副本-这会影响程序的性能。更好的主意是在循环内移动该变量(my %track
)的声明(这样,每次循环时您都会得到一个新变量),然后只需将对哈希的引用推送到数组中即可。
push @{$hCompilations{$album}} , \%track;
您已经有了获取轨道阵列的代码,因此在该阵列上进行迭代很简单。
my @trackRecs = @{$hCompilations{$albumName}};
foreach my $track (@trackRecs) {
print "$track->{trackName}/$track->{trackArtist}\n";
}
注意,您不需要中间数组:
foreach my $track (@{$hCompilations{$albumName}}) {
print "$track->{trackName}/$track->{trackArtist}\n";
}
首先,您希望将哈希作为单个元素推送,因此不是
push @{$hCompilations{$album}} , %track;
使用
push @{$hCompilations{$album}} , {%track};
在循环中,您可以使用以下方式访问曲目:
foreach my $albumName ( sort keys %hCompilations ) {
print "$albumName\n";
my @trackRecs = @{$hCompilations{$albumName}};
# how do I loop through the trackrecs?
foreach my $track (@trackRecs) {
print $track->{trackName} . "/" . $track->{trackArtist} . "\n";
}
}