Как я узнаю, есть ли в моем массиве похожий элемент? - PullRequest
1 голос
/ 16 февраля 2011

У меня есть этот код, который перечисляет все файлы в моем каталоге:

$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 ]

3 голосов
/ 16 февраля 2011

В Perl, когда вам нужно использовать строку в качестве ключа в структуре данных, вы ищете встроенный тип HASH, обозначенный символом %.Приятной особенностью хэшей 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

Чтобы получить в отдельных файлах:1011 * Выше я использовал возвращаемое значение функции 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 голос
/ 16 февраля 2011

Люди очень быстро отвечают здесь :) в любом случае, я выложу свой, просто для справки. По сути, я также использую хэш.

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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...