Re: creating the hierarchy pattern from the input file
by LanX (Saint) on Sep 16, 2021 at 11:40 UTC
|
use strict; # https://perlmonks.org/?node_
+id=11136806
use warnings; # creating the hierarchy patte
+rn from the input file
use Data::Dump qw/pp dd/;
my $tree ={};
while ( my $line =<DATA> ) {
chomp $line;
my @keys = split /@/, $line;
my $ref = $tree;
$ref = ( $ref->{$_} //= {} ) # descend into hashrefs, init
+explicitly when missing
for @keys
}
my $out = pp $tree; # now "d1 => { d1 => {} }," et
+c
# purge
$out =~ s/\Q => {}//g; # ... empty hashes
$out =~ s/\Q => / /g; # ... fat arrows
$out =~ s/\Q},/}/g; # ... trailing commas
print $out;
__DATA__
instreg@d1@d1
instreg@d1@d2
instreg@d2@d1
instreg@d3@d1
instreg@d4@d1
instreg@d5@d1
instreg@d6@d1
instreg@d7@d1
instreg@d8@d1
alureg@d1@d1
alureg@d2@d1
alureg@d3@d1
alureg@d4@d1
alureg@d5@d1
alureg@d6@d1
alureg@d7@d1
alureg@d8@d1
pgmctr@d1@d1
pgmctr@d2@d1
pgmctr@d3@d1
pgmctr@d4@d1
pgmctr@d5@d1
pgmctr@m1
pgmctr@m2
pgmctr@m3
pgmctr@m4
pgmctr@m5
OUTPUT:
-*- mode: compilation; default-directory: "d:/tmp/pm/" -*-
Compilation started at Thu Sep 16 13:39:54
C:/Strawberry/perl/bin\perl.exe -w d:/tmp/pm/text_to_tree.pl
{
alureg {
d1 { d1 }
d2 { d1 }
d3 { d1 }
d4 { d1 }
d5 { d1 }
d6 { d1 }
d7 { d1 }
d8 { d1 }
}
instreg {
d1 { d1, d2 }
d2 { d1 }
d3 { d1 }
d4 { d1 }
d5 { d1 }
d6 { d1 }
d7 { d1 }
d8 { d1 }
}
pgmctr {
d1 { d1 }
d2 { d1 }
d3 { d1 }
d4 { d1 }
d5 { d1 }
m1,
m2,
m3,
m4,
m5,
}
}
Compilation finished at Thu Sep 16 13:39:55
alternatively
use Data::Dumper (which is core) and change the settings for => ("Pair") and so on.
See https://metacpan.org/pod/Data%3A%3ADumper#Configuration-Variables-or-Methods
update
added more comments to code | [reply] [d/l] [select] |
|
|
| [reply] |
|
|
| [reply] [d/l] |
|
|
Please read the whole post.
| [reply] |
Re: creating the hierarchy pattern from the input file
by tybalt89 (Monsignor) on Sep 16, 2021 at 10:04 UTC
|
Well, here's a best guess...
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11136806
use warnings;
my %hash;
while( <DATA> )
{
chomp;
my $code = s/\@/}{/gr;
eval "\$hash{$code}++";
}
#use Data::Dump 'dd'; dd \%hash;
sub nest
{
my $h = shift;
my $answer = '';
if( ref $h )
{
for my $k ( sort keys %$h )
{
$answer .= ref( $h->{$k} )
? "$k {\n" . nest( $h->{$k} ) =~ s/^/\t/gmr . "}\n"
: $k . "\n";
}
}
$answer;
}
local $_ = nest \%hash;
s/\w\K\n\s*(?=\w)/,/g;
print;
__DATA__
instreg@d1@d1
instreg@d1@d2
instreg@d2@d1
instreg@d3@d1
instreg@d4@d1
instreg@d5@d1
instreg@d6@d1
instreg@d7@d1
instreg@d8@d1
alureg@d1@d1
alureg@d2@d1
alureg@d3@d1
alureg@d4@d1
alureg@d5@d1
alureg@d6@d1
alureg@d7@d1
alureg@d8@d1
pgmctr@d1@d1
pgmctr@d2@d1
pgmctr@d3@d1
pgmctr@d4@d1
pgmctr@d5@d1
pgmctr@m1
pgmctr@m2
pgmctr@m3
pgmctr@m4
pgmctr@m5
Outputs:
alureg {
d1 {
d1
}
d2 {
d1
}
d3 {
d1
}
d4 {
d1
}
d5 {
d1
}
d6 {
d1
}
d7 {
d1
}
d8 {
d1
}
}
instreg {
d1 {
d1,d2
}
d2 {
d1
}
d3 {
d1
}
d4 {
d1
}
d5 {
d1
}
d6 {
d1
}
d7 {
d1
}
d8 {
d1
}
}
pgmctr {
d1 {
d1
}
d2 {
d1
}
d3 {
d1
}
d4 {
d1
}
d5 {
d1
}
m1,m2,m3,m4,m5
}
If this is not what you are looking for, please show the exact output you want, especially for pgmctr,
which as LanX has pointed out, has an array/hash conflict.
P.S. This is also sure to upset the 'eval' haters :)
| [reply] [d/l] [select] |
|
|
DB<41> $ref= $tree
DB<42> x @keys = split /@/,'a@b@c'
0 'a'
1 'b'
2 'c'
DB<43> $ref = ($ref->{$_}//={})for @keys
DB<44> x $tree
0 HASH(0xaa630cf0)
'a' => HASH(0xaa6204a0)
'b' => HASH(0xaa6719b0)
'c' => HASH(0xaa75baa0)
empty hash
DB<45>
Update
And so on for each line
DB<45> x @keys = split /@/,'a@b@d'
0 'a'
1 'b'
2 'd'
DB<46> $ref= $tree
<= ($ref->{$_}//={})for @keys
DB<48> x $tree
0 HASH(0xaa630cf0)
'a' => HASH(0xaa6204a0)
'b' => HASH(0xaa6719b0)
'c' => HASH(0xaa75baa0)
empty hash
'd' => HASH(0xaa672e30)
empty hash
DB<49>
| [reply] [d/l] [select] |
|
|
| [reply] |
|
|
> maybe the best solution for people abusing the monastery as code writing service ;)
Yes, this seems to be getting worse lately!
I'm reminded of Ian Phillipps' little perl program-generator of 1990.
All it did was ask you to enter the program you wanted written ...
then post to comp.lang.perl with a title of "I don't think perl can $program_you_wanted_written".
In those days, there were plenty of Perl zealots eager to prove that Perl could indeed do it! :)
(Mentioned at The Lighter Side of Perl Culture (Part I): Introduction).
| [reply] [d/l] |
|
|
|
|
|
|
|
| [reply] |
|
|
| [reply] |
|
|
Here's an updated version using ideas stolen borrowed from LanX.
It sounds like the provided input might be a section of a larger file. If so, you could either
pass in the section as a string and use the reference open as shown, or pass in the file handle ($fh) and also
specify some input line that will cause a return to caller.
#!/usr/bin/perl
use strict; # https://perlmonks.org/?node_id=11136806
use warnings;
my $inplacefile = <<'END';
instreg@d1@d1
instreg@d1@d2
instreg@d2@d1
instreg@d3@d1
instreg@d4@d1
instreg@d5@d1
instreg@d6@d1
instreg@d7@d1
instreg@d8@d1
alureg@d1@d1
alureg@d2@d1
alureg@d3@d1
alureg@d4@d1
alureg@d5@d1
alureg@d6@d1
alureg@d7@d1
alureg@d8@d1
pgmctr@d1@d1
pgmctr@d2@d1
pgmctr@d3@d1
pgmctr@d4@d1
pgmctr@d5@d1
pgmctr@m1
pgmctr@m2
pgmctr@m3
pgmctr@m4
pgmctr@m5
END
my $filename = \$inplacefile; # FIXME change to filename with no refer
+ence
open my $fh, '<', $filename or die $!; # FIXME improve error message
my $hash = {};
while( <$fh> )
{
my $ref = $hash;
$ref = $ref->{$_} //= {} for split /\@|\n/;
}
#use Data::Dump 'dd'; dd $hash;
sub nest
{
my $h = shift;
join '', map {
%{$h->{$_}} ? "$_ {\n" . nest( $h->{$_} ) =~ s/^/\t/gmr . "}\n" :
+"$_\n";
} sort keys %$h;
}
print nest($hash) =~ s/\w\K\n\s*(?=\w+$)/,/gmr;
Same output as before.
| [reply] [d/l] |
|
|
| [reply] |
Re: creating the hierarchy pattern from the input file
by The Perlman (Scribe) on Sep 16, 2021 at 08:18 UTC
|
| [reply] |
|
|
> built a tree of nested hashes with arrays as leaves
That's not possible, because the input has varying depth causing conflicts.
One parent level can't be hash and array at the same time.
And hashes can't have duplicate keys. So maybe he rather wants nested arrays?
If the OP didn't show code, then he should at least have shown valid target data.
Update
Or maybe the OP doesn't want data but just text displaying a tree?
| [reply] |
|
|
Hi Ron,
Yes but the array length keeps changing , so how do we consider that ?
The expectation is the last element should be the value and all other elements should be the keys to each other , and also is there should be no repetition of the keys it should dbe uniq
Thanks
| [reply] |
|
|
"and also is there should be no repetition of the keys it should dbe uniq"
What?
| [reply] |