Perl: преобразовать массив хэшей в матрицу - PullRequest
3 голосов
/ 24 января 2012

У меня есть массив хэшей, многие из которых имеют общие ключи.

Я хотел бы преобразовать это в матрицу для анализа в [R], чтобы каждая строка представляла хеш, а каждый уникальный ключ - это столбец, который (пустой) или «.»или 'NA', если хеш не содержит этот конкретный ключ.

В настоящее время я планирую найти каждый уникальный ключ в массиве хэшей и построить свою матрицу, просматривая каждый из них для каждого хэша ... но должен быть лучший способ ??

Спасибо!

Пример:

my %hash_A = (
  A=> 12,
  B=> 23,
  C=> 'a string'
  );
my %hash_B = (
  B=> 23,
  C=> 'a different string',
  D=> 99
  );

Чтобы дать:

A,B,C,D
12,23,'a string',NA
NA, 23, 'a different string', 99

Ответы [ 3 ]

2 голосов
/ 24 января 2012

Если вы убедитесь, что каждый из ваших хэшей инициализирован как «NA» для каждого возможного ключа, то у вас в основном есть матрица, и вы можете просто распечатать ее ... (данные должны быть перезаписаны, когда они не "NA" «)

Если вы не можете инициализировать их, просто заранее проследите за всеми возможными ключами, а затем зациклите их при печати структуры данных (вместо циклического перебора ключей каждого отдельного хэша).

my @possibleKeys = keys %possibleKeys;
foreach my $hashref (@arrayOfHashes)
    foreach my $key (@possibleKeys) {
        if(!defined ${$hashref}{$key}) { 
            print "NA "; 
        else { 
            print "$hashref{$key} "; 
        }
    print "\n"; 
    }
}

Edit: keys %possibleKeys будет возвращать по-разному упорядоченный массив для каждого вызова (см. http://perldoc.perl.org/functions/keys.html), поэтому ключи должны храниться в массиве для сохранения порядка.

1 голос
/ 24 января 2012
my @a = ( keys %hash_A, keys %hash_B );
my %r;
@r{@a} = @a;
for my $h ( \%r, \%hash_A, \%hash_B ) {
    print join( ', ', map { $$h{$_} ||= 'NA' } sort keys %r ), "\n";
}
1 голос
/ 24 января 2012

Это должно преобразовать массив хэшей в двумерный массив (@output1).

Все выходные ячейки, в которых не было соответствующего входного значения, будут заполнены 'NA'. (Если вы не возражаете против отображения неподписанных ячеек на undef, то это можно сделать более кратко - см. @output2.)

Массив @keys скажет, какой хэш-ключ относится к каждой позиции индекса в выходных строках.

my @array_of_hashes = ...;

my %keys

for my $hash (@array_of_hashes) {
    @keys{keys %$hash} = ();
}

my @keys = sort keys %keys;

my @output1 = map {
    my $hash = $_;

    [ map { exists $$hash{$_} ? $$hash{$_} : 'NA' } @keys ];
} @array_of_hashes;

my @output2 = map [ @$_{@keys} ] => @array_of_hashes;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...