【问题标题】:Convert a flat datastructure into a tree将平面数据结构转换为树
【发布时间】:2015-11-08 20:25:12
【问题描述】:

我有一个哈希数组。数组中的每个元素都是层次树中的一个节点,并且具有父级的参考数据。我将在树中拥有成千上万个节点...本质上必须将一组未知的节点转换为 JSON(如下所示)以用于 http://bl.ocks.org/robschmuecker/7880033

更新:position_id 是异端树中的一个节点。 Placement_id 是父节点的 position_id(邻接参照树)。

更新:这是来自 DBIx::Tree::NestedSet(自定义)修改版本的嵌套集和邻接结果的完整 AoH Data::Dumper 结果。

$VAR1 = [
          {
            'lft' => '673',
            'id' => '109',
            'date_created' => '2015-08-15',
            'level' => '7',
            'user_id' => '13',
            'placement_id' => '11',
            'position_id' => '13',
            'status' => '1',
            'structure_id' => '1',
            'rght' => '684'
          },
          {
            'placement_id' => '13',
            'position_id' => '22',
            'status' => '1',
            'structure_id' => '1',
            'rght' => '679',
            'lft' => '674',
            'date_created' => '2015-08-15',
            'id' => '116',
            'level' => '8',
            'user_id' => '22'
          },
          {
            'user_id' => '101',
            'level' => '9',
            'id' => '200',
            'date_created' => '2015-08-15',
            'lft' => '675',
            'rght' => '676',
            'structure_id' => '1',
            'status' => '1',
            'position_id' => '101',
            'placement_id' => '22'
          },
          {
            'date_created' => '2015-08-15',
            'id' => '201',
            'level' => '9',
            'user_id' => '374',
            'lft' => '677',
            'structure_id' => '1',
            'rght' => '678',
            'placement_id' => '22',
            'position_id' => '374',
            'status' => '1'
          },
          {
            'lft' => '680',
            'user_id' => '95',
            'level' => '8',
            'id' => '117',
            'date_created' => '2015-08-15',
            'status' => '1',
            'position_id' => '95',
            'placement_id' => '13',
            'rght' => '681',
            'structure_id' => '1'
          }
        ];

这是目标,对于这个例子,我需要结束:

{
    "name": "13",
    "children": [
        {
            "name": "22",
            "children": [
                {
                    "name": "101"
                },
                {
                    "name": "374"
                }
            ]
        },
        {
            "name": "95"
        }
    ]
}

您还可以在这里看到我想要达到的格式(减去大小): http://bl.ocks.org/robschmuecker/7880033#flare.json

我失败的方法包括循环遍历哈希数组以创建递归哈希哈希,然后可以与JSON Perl module 一起使用以创建我需要的实际 JSON。

【问题讨论】:

  • 如果第一个哈希值是 1 级而不是 7 级,它会是什么样子?
  • 看起来是一样的。级别本身是更大树中的整体级别。所以,13 是整个树的第 7 级,但是这个组的第 1 级。
  • @melpomene 我认为这只是遥远的关系,因为该问题的解决方案需要 DATA 并创建一个哈希数组。我有一个哈希数组,我需要将其制成 HOH。
  • @Melplacement_id 是什么意思?重要吗?

标签: perl recursion data-structures tree


【解决方案1】:
my $data = [
   {  position_id => 123, placement_id => undef },
   {  position_id => 456, placement_id => 123 },
   {  position_id => 789, placement_id => 123 },
   # ...
];

my $roots;
{
   my %recs_by_name;
   my %children_by_parent_name;
   for my $row (@$data) {
      my $name        = $row->{position_id};
      my $parent_name = $row->{placement_id};

      my $rec = {
         name => $name,
      };

      push @{ $children_by_parent_name{$parent_name // 'root'} }, $rec;
      $recs_by_name{$name} = $rec;
   }

   $roots = delete($children_by_parent_name{root}) || [];

   for my $name (keys(%children_by_parent_name)) {
      my $children = $children_by_parent_name{$name};
      if ( my $rec = $recs_by_name{$name} ) {
         $rec->{children} = $children;
      } else {
         die("Parent $name doesn't exist.\n");
         push @$roots, @$children;
      }
   }
}

print(Dumper($roots));

经过测试。

您似乎可以使用每个节点的深度 (level)。如果您的数据按递增深度排序,则可以使用更简单的代码。

【讨论】:

  • 请告诉我你的方法你没有提供任何解释。不确定谁对您的答案投了反对票,或者确切原因。但是,您的回答没有帮助,而且似乎有问题,但我会让您解释一下。
  • 每一行都是独立的,所以我不确定有什么要解释的。您需要哪方面的帮助?
  • 未创建“children”键以具有完整的嵌套 HOH。请参阅编辑。
  • @Mel,你抛弃了\%children_by_parent_name,而你应该抛弃$roots。我认为这很明显,因为它是代码末尾存在的唯一变量,但我让它变得更加明显。
  • 您是说使用 JSON 编码数据结构也有问题吗?如果是这样,那是一个单独的问题,应该是一个单独的问题。展示你的努力,并清楚地说明你遇到了什么问题。
【解决方案2】:

虽然是 @ikegami 最终回答了导致解决方案的问题。我相信以下改编增加了 4 个我认为有帮助的重要元素/说明,并且认为阅读此问题和答案的其他人也会觉得有用。

1- 将所有键、值对从原始 AoH 清除到生成的 HOH。查看while循环。

2- 一个子节点计数器。

3- 包含和使用来自JSON的encode_json函数

4- 结果也是一个以哈希作为第一个元素的数组。新手(像我一样)可能会发现传递给 encode_json 的显式 @{$roots}[0] 很有帮助。

起初我在我的问题中发布了一个类似的修改解决方案作为更新,但被警告说这是不礼貌的,并被指示发布答案。

@ikegami 的解决方案的核心值得称赞。

sub get_jsonTree {
    my ($array_of_hashes_ref) = @_;

    my $roots;
    my %recs_by_name;
    my %children_by_parent_name;
    my %count;
    for my $row (@$array_of_hashes_ref) {
        my $name        = $row->{position_id};
        my $parent_name = $row->{placement_id};

        my $rec = {
            name => $name,
        };

        ## Added to loop through all key,value pairs and add them to $rec
        while ( my ($key, $value) = each(%$row) ) {
            $rec->{$key} = $value;
        }

        ##Added To Count Child Nodes
        $count{$parent_name} = 0 if (!$count{$parent_name});        
        $rec->{'child_count'} = $count{$parent_name};
        $count{$parent_name}++;

        push @{ $children_by_parent_name{$parent_name // 'root'} }, $rec;
        $recs_by_name{$name} = $rec;
    }

    $roots = delete($children_by_parent_name{root}) || [];

    for my $name (keys(%children_by_parent_name)) {
        my $children = $children_by_parent_name{$name};
        if ( my $rec = $recs_by_name{$name} ) {
            $rec->{children} = $children;
        } else {
            $util{'test'} .=  "Parent $name doesn't exist.\n<BR>";
            push @$roots, @$children;
        }
    }

    use JSON;
    my $json_str = encode_json(@{$roots}[0]);

    return $json_str;
}

my $array_of_hashes_ref = [
    {  position_id => 123, placement_id => undef },
    {  position_id => 456, placement_id => 123 },
    {  position_id => 789, placement_id => 123 },
    # ...
];

my $json_str = &get_jsonTree($array_of_hashes_ref);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-04
    • 1970-01-01
    • 2018-02-06
    • 1970-01-01
    相关资源
    最近更新 更多