Как правильно рассчитать длину полей в CSV-элементе с помощью Perl? - PullRequest
2 голосов
/ 25 января 2010

У меня есть данные и мне нравится делать простую операцию while со скриптом Perl. Вот небольшое извлечение из набора данных:

"номер", "код", "страна", "гамма", "X1", "X2", "X3", "X4", "X5", "X6" 1, "DZA", "Алжир", "0,01", 7.44,47.3,0.46,0,0,0.13 2, "АГО", "Ангола", "0,00", 6.79, "NULL", 0.21,1,0,0.28 3, "БЕН", "Бенин", "- 0,01", 7.02,38.9,0.27,1,0,0.05 4, "BWA", "Ботсвана", "0,06", 6.28,45.7,0.42,1,0,0.07 5, "ХВО", "Буркина-Фасо", "0,00", 6,15,36,3,0.08,1,0,0.05 6, "BDI", "Бурунди", "0,00", 6.38,41.8,0.18,1,0,0

Скрипт должен считать длину каждого , отдельного поля и хранить самые высокие значения в массив.

Однако сохранение не работает должным образом. Вот часть кода:

@maxl = map length, @terms;

while(`<INFILE>`) {
$_ =~ s/[\"\n]//g ;
@terms = split/$sep/, $_;
@lengths = map length, @terms;
for($k = 0, $k <= $#terms, $k++) { 
    if($lengths[$k] > $maxl[$k]) {
    $maxl[$k] = $lenghts[$k];
    }
}
print "@lengths\n";
}

Теперь @maxl использует более раннюю часть кода, где он использует вторую строку набора данных. Когда я использую команду print только для просмотра значений операции @maxl, я получаю:

1 3 7 4 4 4 4 1 1 5

В цикле while я использовал другой оператор print, просто чтобы увидеть другие значения, я получаю:

1 3 6 4 4 4 4 1 1 4
1 3 5 5 4 4 4 1 1 4
1 3 8 4 4 4 4 1 1 4
1 3 12 4 4 4 4 1 1 4
1 3 7 4 4 4 4 1 1 1
1 3 8 4 4 4 4 1 1 4
1 3 10 4 4 4 4 1 1 4
1 3 16 5 4 4 4 1 1 4
2 3 4 5 3 4 4 1 1 4
2 3 7 4 4 4 4 1 1 4
2 3 5 4 4 4 4 1 1 4
2 3 5 4 4 4 4 1 1 4
2 3 8 4 4 4 4 1 1 4
2 3 5 4 4 4 1 1 1 4

Четвертый столбец, например, имеет значения, очевидно, больше 3. Цикл while должен был сохранять самые большие значения и подставлять эти значения в @maxl.

Что пошло не так?


... в цикле for запятая неверна

for($k = 0, $k <= $#terms, $k++)

однако, после очистки это все еще кажется проблемой ...

1 Ответ

9 голосов
/ 25 января 2010

здесь опечатка $maxl[$k] = $lenghts[$k]; для начинающих (которые «используют строгое» поймали бы)

рассмотрите возможность использования Text :: CSV для более надежного анализа данных, разделенных запятыми (он также может обрабатывать другие разделители):

#!/usr/bin/perl
use strict;
use warnings;
use Text::CSV;

my $csv = Text::CSV->new();
my @max_lengths;

while ( my $line = <INFILE> ) {

    die "Unable to parse '$line'" unless $csv->parse($line);

    my @column_lengths = map { length } $csv->fields();

    for my $i ( 0 .. $#column_lengths ) {
        if ( $column_lengths[$i] > ($max_lengths[$i] || 0) ) {
            $max_lengths[$i] = $column_lengths[$i];
        }
    }
}

print "MAX LENGTHS OF EACH FIELD: @max_lengths\n";
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...