开发者

How would I know if there is any similar element in my array?

I have this code which lists all files in my directory:

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

which returns an array containing something like this:

开发者_如何学Python
$array (0 => 'ipax3_2011_01_27.txt', 1 => 'ipax3_2011_02_01.txt', 2 => 'ipax3_2011_02_03.txt')

My problem here is, how will I store elements 1 => 'ipax3_2011_02_01.txt' and 2 => 'ipax3_2011_02_03.txt' to separate variable as they belong to the same month and year(2011_02)?

Thanks!


In Perl, when you need to use a string as the key in a data structure, you are looking for the HASH builtin type, designated by the % sigil. A nice feature of Perl's hashes is that you do not have to pre-declare a complex data structure. You can use it, and Perl will infer the structure from that usage.

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";
    }
}

which prints:

2011_01 has 1 file
2011_02 has 2 files

To get at the individual files:

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

Above I used the return value of the keys function as both the list to iterate over, and as the number of days. This is possible because keys will return all of the keys when in list context, and will return the number of keys in scalar context. Context is provided by the surrounding code:

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

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

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

In the last example, each value in %ipax is a reference to a hash. Since keys takes a literal hash, you need to wrap $ipax{$year_month} in %{ ... }. In perl v5.13.7+ you can omit the %{ ... } around arguments to keys and a few other data structure access functions.


People are responding really fast here :) anyway, I'll post mine, just for your reference. Basically, I'm also using a hash.

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;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜