Thread "Beliebig" tiefes Hash mit keys aus Array erstellen (22 answers)
Opened by shi8dao at 2011-06-21 08:35

topeg
 2011-06-21 17:57
#149835 #149835
User since
2006-07-10
2611 Artikel
BenutzerIn

user image
Willst du den Baum nachträglich noch durcharbeiten, so kannst du es so machen:

more (19.9kb):
Code (perl): (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my @var = (
  ['Hund/Katze/Maus', 10],
  ['Hund/Katze/Igel',  9],
  ['Hund/Katze/Hase',  8],
  ['Wolf/Katze/Maus',  7],
  ['Wolf/Katze/Igel',  6],
  ['Wolf/Katze/Hase',  5],
  ['Hund/Tiger/Maus',  4],
  ['Hund/Tiger/Igel',  3],
  ['Hund/Tiger/Hase',  2],
  ['Wolf/Tiger/Maus',  1],
);

my $hashref = {};
my $deep=[];
add($hashref,[split('/',$_->[0])],$_->[1]) for(@var);

print Dumper($hashref);

my $summe=0;
traverse($hashref,sub{ $summe+=shift()});
print "Summe = $summe\n";

$summe=0;
traverse($hashref->{Hund},sub{ $summe+=shift()});
print "Summe{Hund} = $summe\n";

for my $pos (0..3)
{
  my $summe=0;
  print "Summen POS($pos) = \n";
  traverse_deep(
      $hashref,
      sub{ $summe=0; print "  Path: ".join('/',@{$_[1]})." = "; 1},
      sub{ $summe+=shift() },
      sub{ print "$summe\n"; },
      $pos,
    );
  print "\n";
}


########################################################

sub add
{
  my $tmp = \shift();
  $tmp=\$$tmp->{$_} for(@{shift()||[]});
  $$tmp=shift();
}

sub traverse_deep
{
  my $tree=shift;
  my $cmd_start=shift || sub{};
  my $cmd_run=shift || sub{};
  my $cmd_end=shift || sub{};
  my $deep=shift || 0;
  my $path=shift || [];
  if($deep && $tree && ref($tree) eq 'HASH')
  {
    for(keys(%$tree))
    {
      traverse_deep(
          $tree->{$_},
          $cmd_start,
          $cmd_run,
          $cmd_end,
          $deep-1,
          [@$path,$_],
        );
    }
  }
  elsif($cmd_start->($tree,$path))
  {
    traverse($tree,$cmd_run);
    $cmd_end->($tree,$path);
  }
}

sub traverse
{
  my $tree=shift;
  my $cmd=shift || sub{};
  if($tree && ref($tree) eq 'HASH')
  { traverse($_,$cmd) for(values(%$tree)); }
  else
  { $cmd->($tree); }
}


Bedenke aber, dass das unter Umständen viel mehr Zeit braucht als die Nötigen Daten direkt bei der Erzeugung zu sammeln. Das hängt von der Tiefe und Umfang des Baumes zusammen.

View full thread "Beliebig" tiefes Hash mit keys aus Array erstellen