neversaint has asked for the wisdom of the Perl Monks concerning the following question:

Most Respected Masters,
Given this HoHoA
my %HoHoA = ( 'set1' => { 'key1_set1' => [ 'some arrays' ], 'key2_set1' => [ 'some arrays' ], }, 'set2' => { 'key1_set2' => [ 'some arrays' ], 'key2_set2' => [ 'some arrays' ], }, 'set3' => { 'key1_set3' => [ 'some arrays' ], 'key2_set3' => [ 'some arrays' ], }, 'set4' => { 'key1_set4' => [ 'some arrays' ], 'key2_set4' => [ 'some arrays' ], 'key3_set4' => [ 'some arrays' ], }, );
How can I get this:
key1_set1 - key1_set2 key1_set1 - key2_set2 key1_set1 - key1_set3 key1_set1 - key2_set3 key1_set1 - key1_set4 key1_set1 - key2_set4 key1_set1 - key3_set4 key2_set1 - key1_set2 key2_set1 - key2_set2 key2_set1 - key1_set3 key2_set1 - key2_set3 key2_set1 - key1_set4 key2_set1 - key2_set4 key2_set1 - key3_set4 ... key1_set3 - key1_set4 key1_set3 - key2_set4 key1_set3 - key3_set4 key2_set3 - key1_set4 key2_set3 - key2_set4 key2_set3 - key3_set4
What I aim to do is to get pairs of secondary keys that don't come from the same primary key. And once they are evaluated they don't need to be evaluated again. I hope my example above is clear.
Also note that the size of the HoHoA may vary. Now it is 4 (from "set1" to "set4") other case maybe 10 (from "set1" to "set10"), etc. My best attempt is this which is still far from correct:
foreach my $set ( sort keys %HoHoA) { print "$set\n"; my @key = keys %{$HoHoA{$set}}; for ( my $i = 0; $i<@key; $i++ ) { for (my $j=$i+1; $j<@key; $j++ ) { print "$key[$i] - $key[$j]\n"; } } } # Am I attacking the problem correctly?
Sorry I really don't have a strong background in Computer Science. Please be patient with me.

Replies are listed 'Best First'.
Re: Getting Pairs of 2nd-ary Keys in HoHoA
by Forsaken (Friar) on Jul 21, 2005 at 07:14 UTC
    As always, TIMTOWTDI :P
    my @sets = sort(keys(%HoHoA)); while(@sets) { my $set1 = shift(@sets); foreach my $part1 (sort(keys(%{$HoHoA{$set1}}))) { #note that the earlier shift has already taken off #the part we don't want to match against foreach my $set2 (@sets) { foreach my $part2 (sort(keys(%{$HoHoA{$set2}}))) { print "$part1 - $part2\n"; } } } }
    Note that this is still pretty damn inefficient because it sorts the sets of keys to match with every time it goes through the loop, but then again, this *does* sound like a school assignment, so that part is up to the OP. What looks to me to be the most efficient solution is to first make a pass through the entire HoH(the fact that the keys point at arrays in this specific case is entirely irrelevant) and make a sorted array for each set of keys and assign these to a HoA instead. Then, once the sorting is done you could simply foreach through the HoA and do the matching you wanted. If this is indeed, as i expect, a school assignment the latter solution would be, especially when the data gets bigger, a lot more efficient than the one I gave you and thus get you a better grade ;-)


    Remember rule one...
Re: Getting Pairs of 2nd-ary Keys in HoHoA
by jbrugger (Parson) on Jul 21, 2005 at 06:06 UTC
    ok, clear, i see what you want:
    (probably can be done better, but works :)
    my $aant = (keys %HoHoA); for (my $i = 1; $i<= $aant; $i++) { foreach my $keyA(sort keys %{$HoHoA{'set'.$i}}) { for (my $y = $i+1; $y<= $aant; $y++) { foreach my $keyB(sort keys %{$HoHoA{'set'.$y}}) { print "$keyA - $keyB\n"; } } } }
    #output:
    "We all agree on the necessity of compromise. We just can't agree on when it's necessary to compromise." - Larry Wall.
      Thanks so much jbrugger. I don't mean to trouble you much. But how can I make these parts:
      %{$HoHoA{'set'.$i}}
      and this:
      %{$HoHoA{'set'.$y}}
      Be made more flexible. Because this secondary key (key1_set1 ..etc) can be "totally random". I wrote it that way for easiness in explaining. Really hope to hear from you again.
      Yes jbrugger, It should be there. (I'll try to draw a diagram for that). I hope this drawing won't complicate the intention:
      set1' => { 'key1_set1' => [ 'some arrays' ], --->- 'key2_set1' => [ 'some arrays' ], +++>|+++>+ }, | + | + 'set2' => { | + 'key1_set2' => [ 'some arrays' ], <---|<+++> 'key2_set2' => [ 'some arrays' ], <---|<+++> }, | + | + etc...until 'set3' => { | + 'key1_set3' => [ 'some arrays' ], <---|<++++ ###> 'key2_set3' => [ 'some arrays' ], <---|<++++ ###> }, | + # | + # 'set4' => { | + # 'key1_set4' => [ 'some arrays' ], <---|<++++ <### 'key2_set4' => [ 'some arrays' ], <---|<++++ <### 'key3_set4' => [ 'some arrays' ], <---|<++++ <### },
Re: Getting Pairs of 2nd-ary Keys in HoHoA
by tlm (Prior) on Jul 21, 2005 at 12:50 UTC
      Boy! Mindblowing indeed!
      Thanks a lot Mr.tlm. But can you explain what is `memoization`?
      And if you don`t mind little explanation, why you do each step that way?

        But can you explain what is `memoization`?

        "Memoization" is a standard speed-optimization technique: one caches often-used results so they don't need to be recomputed.

        And if you don`t mind little explanation, why you do each step that way?

        the lowliest monk