Как мне перейти на дереве к следующему ребенку? - PullRequest
2 голосов
/ 25 января 2020

Я пытаюсь построить дерево самостоятельно. Я начинаю с анонимного ха sh и создаю первый узел («там»). С этого момента я хочу создать дочерний узел, но то, что я пытался, не сработало.

use Data::Dumper;
$tree = {};
$tree->{'these'} = {};
$tree = $tree->{'these'};
$tree->{'are'} = {};
print Dumper $tree;

$tree = $tree->{'these'}; не перемещает $tree в анонимный ха sh. На выходе получается

$VAR1 = {
          'are' => {}
        };

, но я хотел, чтобы оно было

$VAR1 = {
          'these' => {
                     'are' => {}
                     }
        };

Любая идея очень ценится.

Ответы [ 2 ]

2 голосов
/ 25 января 2020

Давайте начнем с просмотра последних двух строк, которые вы написали:

$tree->{'are'} = {};
print Dumper $tree;

После этого как $tree может быть ссылкой на га sh, которая содержит только ключ these как вы говорите, хотите?

Проблема в том, что вы пытаетесь использовать $tree для двух разных вещей:

  • Ссылка на узел root.
  • Ссылка на узел, к которому вы хотите добавить элементы.

Эти два хэша / узла не всегда одинаковы, поэтому нам нужны две переменные. На самом деле, я буду использовать три для полной ясности.

  • $tree, ссылка на узел root.
  • $node узел, который мы создаем.
  • $parent узел, в который мы хотим вставить.

Мы начинаем с создания root узел и назначить его $tree

my $tree = {};

Мы не хотим терять связь с узлом root, поэтому мы никогда больше не назначим $tree. Мы можем присвоить элементам ha sh, на которые ссылается $tree, хотя.

При следующей вставке мы хотим вставить в узел root.

my $parent = $tree;

Теперь пришло время начать добавлять новые узлы.

my $node = {};
$parent->{these} = $node;

При следующей вставке мы хотим вставить во вновь созданный узел.

$parent = $parent->{these};

Вставляем снова.

my $node = {};
$parent->{are} = $node;

И это все! Все вместе:

use strict;     # ALWAYS use this.
use warnings;   # ALWAYS use this.

use Data::Dumper qw( Dumper );

my $tree = {};
my $parent = $tree;

{
   my $node = {};
   $parent->{these} = $node;
   $parent = $parent->{these};
}

{
   my $node = {};
   $parent->{are} = $node;
   $parent = $parent->{are};
}

print(Dumper($tree));

Если это понятно, мы можем немного упростить.

use strict;     # ALWAYS use this.
use warnings;   # ALWAYS use this.

use Data::Dumper qw( Dumper );

my $tree = {};
my $parent = $tree;

$parent->{these} = {};
$parent = $parent->{these};

$parent->{are} = {};
$parent = $parent->{are};

print(Dumper($tree));

Мы даже можем сделать еще один шаг вперед!

use strict;     # ALWAYS use this.
use warnings;   # ALWAYS use this.

use Data::Dumper qw( Dumper );

my $tree = {};
my $parent = $tree;

$parent = $parent->{these} = {};   # Assignments are performed right-to-left.
$parent = $parent->{are} = {};

print(Dumper($tree));
2 голосов
/ 25 января 2020

Рассмотрим:

use strict;
use warnings;
use Data::Dumper;

my $tree = {};
$tree->{these}->{are} = {};
print Dumper $tree;

Обоснование: ваш исходный код продолжает переназначать новые значения на $tree, перезаписывая ранее присвоенное значение:

$tree->{'these'} = {};       # original assignment
$tree = $tree->{'these'};    # new assignment: now $tree is an empty hash ref
$tree->{'are'} = {};         # new assignment: now $tree contains { are => {} }

Вот еще один способ express Ваше намерение, используя другую переменную:

use strict;
use warnings;
use Data::Dumper;

my $tree = {};
my $child_tree = {};
$child_tree->{are} = {};
$tree->{these} = $child_tree;
print Dumper $tree;

Несвязанное примечание: всегда use strict; use warnings;!

...