我怎么知道我的数组中是否有任何类似的元素?

时间:2011-02-16 01:24:18

标签: arrays perl

我有这段代码,列出了我目录中的所有文件:

$dir = '/var/www/corpIDD/rawFile/';
opendir DIR, $dir or die "cannot open dir $dir: $!";
my @file= readdir DIR;
closedir DIR;

返回一个包含如下内容的数组:

$array (0 => 'ipax3_2011_01_27.txt', 1 => 'ipax3_2011_02_01.txt', 2 => 'ipax3_2011_02_03.txt')

我的问题是,我如何存储元素1 => 'ipax3_2011_02_01.txt'和2 => 'ipax3_2011_02_03.txt'将变量分开,因为它们属于同一个月和一年(2011_02)?

谢谢!

2 个答案:

答案 0 :(得分:3)

在Perl中,当您需要使用字符串作为数据结构中的键时,您正在寻找由HASH sigil指定的%内置类型。 Perl哈希的一个很好的特性是你不必预先声明一个复杂的数据结构。您可以使用它,Perl将根据该用法推断出结构。

my @file = qw(ipax3_2011_01_27.txt ipax3_2011_02_01.txt ipax3_2011_02_03.txt);

my %ipax3;

for (@file) {
    if (/^ipax3_(\d{4}_\d{2})_(\d{2}).txt$/) {
        $ipax3{$1}{$2} = $_
    }
    else {
        warn "bad file: $_\n"
    }
}

for my $year_month (keys %ipax3) {
    my $days = keys %{ $ipax3{$year_month} };
    if ($days > 1) {
        print "$year_month has $days files\n";
    }
    else {
        print "$year_month has 1 file\n";
    }
}

打印:

2011_01 has 1 file
2011_02 has 2 files

获取单个文件:

my $year_month = '2011_02';
my $day        = '01';
my $file       = $ipax3{$year_month}{$day};

上面我使用了keys函数的返回值作为迭代列表和天数。这是可能的,因为keys将在列表上下文中返回所有键,并将返回标量上下文中的键数。上下文由周围的代码提供:

my $number = keys %ipax3; # number of year_month entries

my @keys = keys %ipax3; # contains ('2011_01', '2011_02') 

my @days = keys %{ $ipax{$year_month} };

在上一个示例中,%ipax中的每个值都是对哈希的引用。由于keys采用文字哈希,因此您需要在$ipax{$year_month}中包含%{ ... }。在perl v5.13.7 +中,您可以省略%{ ... }周围keys的参数以及一些其他数据结构访问函数。

答案 1 :(得分:1)

人们在这里反应非常快:)无论如何,我会发布我的,仅供您参考。基本上,我也使用哈希。

use warnings qw(all);
use strict;

my ($dir, $hdir) = 'C:\Work';
opendir($hdir, $dir) || die "Can't open dir \"$dir\" because $!\n";
my (@files) = readdir($hdir);
closedir($hdir);

my %yearmonths;
foreach(@files)
{
    my ($year, $month);
    next unless(($year, $month) = ($_ =~ /ipax3_(\d{4})_(\d{2})/));
    $year += 0;
    --$month;           #assuming that months are in range 1-12
    my $key = ($year * 12) + $month;
    ++$yearmonths{ $key };
}
foreach(keys %yearmonths)
{
    next if($yearmonths{ $_ } < 2);
    my $year = $_ / 12;
    my $month = 1 + ($_ % 12);
    printf "There were %d files from year %d, month %d\n", $yearmonths{$_}, $year, $month;
}