This question I posted on SO (but didn't get any comments) - (link:https://stackoverflow.com/questions/54179876/reorganize-hash-in-specific-format)
Consider the following hash of files:
%files_data = { './GetOpt.pm' => { 'pid' => { '56061' => 1, '56065' => 1 } }, 'file1' => { 'pid' => { '56061' => 2 } }, 'file2' => { 'pid' => { '56065' => 2 } }, './src/bin/perl' => { 'pid' => { '56061' => 1, '56065' => 1 } } };
Also consider the following hash of process_data:
%process_data = ( '56061' => { 'parent' => 'NA', 'name' => 'file1' }, '56069' => { 'parent' => '56065', 'name' => 'echo Hello_file1' }, '56062' => { 'parent' => '56061', 'name' => 'echo Hello_file2' }, '56065' => { 'parent' => '56061', 'name' => 'file2' } );
I would like to iterate through the `$files_data` hash and for each file get the chain of files.
So I'll get the following hash:
%hash = ( 'file1' => { '/src/bin/perl' => 1, 'file2' => { '/src/bin/perl' => 1, './GetOpt.pm' => 1 }, './GetOpt.pm' => 1, } );
I need to follow the pid chain up to the main parent ('NA') for each file.
What would be the most efficient way to solve it? I need some guidance on how to implement it.
I'll try to explain how my logic works and show some code. lets take for example `'./GetOpt.pm'` file. It has a pid `56061` so we go to the `%process_data` and see `'file1'` (which is a file). Also we see that the parent of `56061` is `NA` so we stop and get:
file1 => ./GetOpt.pm But `./GetOpt.pm` has another pid - `56065` so we go to `56065` and see `file2` (which is a file). Then we go to `56061` which has `file1` (which is s file). so we get:
file1 => file2 => ./GetOpt.pm
Combine it:
file1 => { ./GetOpt.pm, file2 => ./GetOpt.pm }
I would like to build a process file chain (only with files). the `%files_data` contains valid files and `%process_data` contains the hierarchy of the process we need to follow.
Some of what I tried to do:
create_proc_tree(\%process_data,\%files_data); sub create_proc_tree { my ($proc_href,$files_href) = @_; my %hash; while (my ($file, $procs) = each %{$files_href}) { foreach my $pid (keys(%{$procs->{'pid'}})) { my $prev_file = $file; do { my $parent_id = $proc_href->{$pid}{parent}; my $parent_name = $proc_href->{$pid}{name}; if ($prev_file eq $parent_name) { $hash{$parent_name} = 1; } else { $hash{$parent_name} = { (%{ $hash{$prev_file} // { +} }, $prev_file) }; delete($hash{$prev_file}); } $prev_file = $parent_name; my $parent_name = $proc_href->{$parent_id}{name}; } while(defined($parent_name)); } } print Dumper(\%hash); # Printing for debug }
It does not quite do what I want. The hierarchy is not valid. I'm not sure what is wrong with the algorithm, it feels like true but the output is not as expected.
I think that its because I counted the data to many times without deleting.
It made me think that this algorithm is not efficient and messy. I have found out that we can use 'eval' in order to convert string to hash:
use Data::Dumper; $abc = "Mouse=>Jerry, Cat=>Tom, Dog=>Spike"; my %hash = eval( "( $abc )" ); print Dumper(\%hash);
Maybe a better approach will be to build a string like and then convert it to hash (although I read a comment saying that it is a bad why to use eval).
Also, I though of finding first the Main parent file and the go until I get the current file. How should I solve this issue? What would be the best approach?

In reply to Reorganizing hash by ovedpo15

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.