Добавление нескольких значений для ввода хеша perl

Мне нужно создать многомерный хэш.

например я сделал:

$hash{gene} = $mrna;
if (exists ($exon)){
  $hash{gene}{$mrna} = $exon;
}
if (exists ($cds)){
  $hash{gene}{$mrna} = $cds;
}

где $gene, $mrna, $exon, $cds уникальные идентификаторы.

Но моя проблема в том, что я хочу, чтобы некоторые свойства $gene и $mrna были включены в хеш. например:

$hash{$gene}{'start_loc'} = $start;
$hash{gene}{mrna}{'start_loc'} = $start;

и т. д. Но возможно ли это для объявления хеша? Если я позвоню $hash{$gene} и то и другое $mrna а также start_loc будет напечатан. Какое может быть решение?

Как бы я добавил несколько значений для одного и того же ключа $ gen и $mrna, являющихся ключами в этом случае.

Любые предложения будут оценены.

2 ответа

Что вам нужно сделать, это прочитать справочное руководство по Perl.

Простой ответ на ваш вопрос:

Хеши Perl могут принимать только одно значение ключа. Однако это единственное значение может быть ссылкой на ячейку памяти другого хэша.

my %hash1 = ( foo => "bar", fu => "bur" };  #First hash
my %hash2;
my $hash{some_key} = \%hash1;   #Reference to %hash1

И ничто не мешает тому первому хешу содержать ссылку на другой хеш. Это черепахи вниз!,

Так что да, вы можете иметь сложную и запутанную структуру с любым количеством дополнительных хешей, сколько захотите. Или смешайте в некоторых массивах тоже.

По разным причинам я предпочитаю -> синтаксис при использовании этих сложных структур. Я считаю, что для более сложных структур это облегчает чтение. Тем не менее, главное, это заставляет вас помнить, что это ссылки, а не реальные многомерные структуры.

Например:

$hash{gene}->{mrna}->{start_loc} = $start;  #Quote not needed in string if key name qualifies as a valid variable name.

Лучше всего думать о вашем хэше как о структуре. Например:

my $person_ref = {};   #Person is a hash reference.
my $person->{NAME}->{FIRST} = "Bob";
my $person->{NAME}->{LAST} = "Rogers";
my $person->{PHONE}->{WORK}->[0] = "555-1234"; An Array Ref. Might have > 1
my $person->{PHONE}->{WORK}->[1] = "555-4444";
my $person->{PHONE}->{CELL}->[0] = "555-4321";
...

my @people;
push @people, $person_ref;

Теперь я могу загрузить массив @people всеми своими людьми или использовать хеш:

my %person;
$person{$bobs_ssn} = $person;   #Now, all of Bob's info is index by his SSN.

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

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

Прочитайте учебник. Тогда попробуй свои силы в этом. Это не так сложно понять. Тем не менее, это может быть медведь для поддержания.

Когда ты сказал use strict; Вы защищаете себя:

my $foo = "bar";
say $Foo;    #This won't work!

Это не сработает, потому что вы не объявили $Foo Вы заявили $foo, use stict; может поймать имена переменных, которые были опечатаны, но:

my %var;
$var{foo} = "bar";
say $var{Foo};    #Whoops!

Это не будет пойман (за исключением, может быть, что $var{Foo} не был инициализирован. use strict; Прагма не может обнаружить ошибки в наборе ключей.

Следующий шаг после того, как вы освоитесь со ссылками, - это перейти на объектно-ориентированный Perl. Для этого тоже есть учебник.

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

 sub last_name {
    my $person = shift;   #Don't worry about this for now..
    my $last_name = shift;

    if ( exists $last_name ) {
      my $person->{NAME}->{LAST} = $last_name;
    }
    return $person->{NAME}->{LAST};
}

Когда я задаю свою фамилию с помощью этой подпрограммы... Я имею в виду метод, я гарантирую, что ключ будет $person->{NAME}->{LAST} и не $person->{LAST}->{NAME} или же $person->{LAST}->{NMAE}, или же $person->{last}->{name},

Основная проблема не в изучении механизмов, а в обучении их применению. Итак, подумайте, как именно вы хотите представлять свои предметы. Это о том, какие поля вы хотите, и как вы собираете эту информацию.

Вы можете попробовать поместить каждое значение в хэш массивов:

my (@gene, @mrna, @exon, @cds);

my %hash;
push  @{ $hash{$gene[$_]} }, [$mrna[$_], $exon[$_], $cds[$_] ] for 0 .. $#gene;

Сюда gene ключ с несколькими значениями ($mrna, $exon, $cds) связано с этим.

Переберите ключи / значения следующим образом:

for my $key (sort keys %hash) {
    print "Gene: $key\t";
        for my $value (@{ $hash{$key} } ) {
            my ($mrna, $exon, $cds) = @$value; # De-references the array
            print "Values: [$mrna], [$exon], [$cds]\n";
        }
}

Может быть полезен ответ на вопрос, который я задавал ранее ( может ли хеш-ключ иметь несколько "подзначений" в perl?).

Другие вопросы по тегам