Нужна помощь в понимании этого построчного файлового процессора - PullRequest
1 голос
/ 18 декабря 2011

Я пытаюсь использовать загруженный код Perl, который включает следующую часть, используемую для чтения входного файла построчно.

Однако я не совсем понимаю, как это работает

  1. Что представляет собой $row[-1]?Можно ли проиндексировать строку из -1?

  2. Как работает $result{$id}{$group[0]}=$group[1];?Это строит двумерный массив для результата?

  3. Что делает $df{$group[0]}++;?Это то же самое, что ++ в C ++?

my $result =();
my $df = ();

while (<FILE>)
{    
   my @row = split;
   my $id = $row[-1];
   for my $i(0 .. $#row - 2)
   {
      my @group = split(/\:/, $row[$i]);
      $result{$id}{$group[0]}=$group[1];
      $df{$group[0]}++;
   }
 }

Ответы [ 4 ]

5 голосов
/ 18 декабря 2011

Вот краткое описание того, как работает этот код.

  • Определите $result и $df.И по какой-то странной причине попробуйте назначить им пустой список, даже если он ничего не делает.

    my $result =();
    my $df = ();
    
  • Считать строку из FILE file-handle,и поместите его в $_ для каждой строки.

    while (<FILE>)
    {
    
  • Разделите $_ на пустое пространство, удаляя первый элемент, если он будет пустым.

      my @row = split;
    
  • Установить $id на последний элемент @row.

      my $id = $row[-1];
    
  • Цикл по всем индексам @row, кроме двух последних,и установите $i в индекс.Это было бы проще написать, если бы предыдущая операция была pop последним элементом конца.Я думаю, что вместо этого должно было быть $#row-1.

      for my $i(0 .. $#row - 2)
      {
    
  • Разделить элемент из @row в местоположении $i, :.

        my @group = split(/\:/, $row[$i]);
    
  • Индекс в %result (не $result).

    Сначала по $id, затем по первому элементу @group.Установка второго значения @group.

        $result{$id}{$group[0]}=$group[1];
    
  • Элемент приращения %df (не $df), к первому значению @group.В конечном итоге устанавливается значение 1, если оно не существовало ранее.

        $df{$group[0]}++;
    
  • Конец for, затем while зацикливается.

      }
    }
    

Вот как бы я написал это.

use strict;
use warnings;
use autodie;

my $filename = 'filename';
open my $fh, '<', $filename;

my %result;
my %df;

while (<$fh>){
  my @row = split;
  my $id = pop @row;
  pop @row; # I assume this should be removed.
  for my $pair (@row){
    my($key,$value) = split(':', $pair);
    $result{$id}{$key} = $value;
    $df{$key}++;
  }
}
2 голосов
/ 18 декабря 2011

Иногда код лучше всего объяснить на примере.

Данный файл содержит следующую строку:

AA:BB CC:DD     CC:DD UNIMPORTANT_COL ID

Хеш %result будет выглядеть так:

(
    ID => {
            AA => 'BB',
            CC => 'DD',
          },
)

Хэш %df считает количество уникальных экземпляров:

(
    AA => 1,
    CC => 2,
)

Дополнительные комментарии

  • $#row - последний индекс @row, который равен 4 в приведенном выше примере. Это означает, что $row[$#row] можно было бы использовать вместо $row[-1]
  • Было бы яснее написать my ( $key, $value ) = split /:/, $group; и использовать их вместо $group[0] и $group[1]
  • Переменная $i здесь не очень полезна. Попробуйте использовать foreach my $group ( @group[0..$#group-2]) { вместо
1 голос
/ 18 декабря 2011
  1. $row[-1] представляет последний элемент массива @row ($row[-2] будет представлять предыдущий элемент и т. Д.)

  2. $result{$id}{$group[0]}=$group[1]использует кучу сокращений perl, на самом деле это то же самое, что и $result->{$id}->{$group[0]} = $group[1].

    Что означает следующее:

    • трактует $result как ссылку на HASH, найтиэлемент в этом HASH, который связан с ключом $id, если таких элементов нет, создайте новый
    • , обработайте этот элемент как ссылку на HASH, найдите элемент в этом HASH, который связанс помощью ключа $group[0], если таких элементов нет, создайте новый
    • , присвойте этому элементу значение $group[1]

    Так что $result является ссылкой наХЭШ ХЭШ.(подробнее об этом см. в Поваренная книга структур данных Perl )

  3. $df{$group[0]}++; увеличивает значение ключа $group[0] в HASH, на которое ссылается $df.Разница с C ++ заключается в том, что когда с ключом не связано значение, оно обрабатывается как 0.

0 голосов
/ 18 декабря 2011
  1. Очевидно, id - это последний столбец в строке, $row[-1] возвращает последний элемент в массиве @row.

  2. $result{$id}{$group[0]}=$group[1] buildsдвумерный HASH, присваивая значение $group[1] комбинации клавиш $id и $group[0]

  3. оператор приращения (++) работает так же, как в C ++

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...