On Oct 31, 2005, at 9:56, Gundala Viswanath wrote:

Here is the example, given this HoA:

my $HoA = {
'flintstones' => [ "fred-1 foo-2", "barney-1 bar-2" ],
'jetsons' => [ "george-1 foo-2", "jane-1 bar-2"],
};


How can I convert them to an AoH

my $AoH = [ # Desired results.

{
'flinstones' => "fred-1 foo-2",
'jetsons' => "george-1 foo-2"
},
{
'flinstones' => "fred-1 foo-2",
'jetsons' => "jane-1 bar-2"
},
{
'flinstones' => "barney-1 bar-2",
'jetsons' => "george-1 foo-2"
},
{
'flinstones' => "barney-1 bar-2",
'jetsons' => "jane-1 bar-2"
},

];

Looks like you want all the possible permutations of the values (within each key). If that's right this is a possible solution. I wrote this code based on iterators (inspired by HOP), in case the structure is not small:

use strict;
use warnings;

use Data::Dumper;


my $HoA = {
    'flintstones' => [ "fred-1 foo-2", "barney-1 bar-2" ],
    'jetsons'     => [ "george-1 foo-2", "jane-1 bar-2"],
};

print Dumper(HoA_to_AoH($HoA));

sub HoA_to_AoH {
    my ($HoA) = @_;

    my @keys = keys %{$HoA};
    return [] if not @keys;

    my @AoH = ();

    my $nkeys = @keys;
    my $nvals = @{$HoA->{$keys[0]}};
    my $iter = indexes($nvals, $nkeys);
    while (my $idxs = $iter->()) {
        my %H = ();
        my $i = 0;
        for my $k (@keys) {
            $H{$k} = $HoA->{$k}[$i];
            ++$i;
        }
        push @AoH, \%H;
    }

    return [EMAIL PROTECTED];
}

# Returns an iterator that generates all permutations with
# repetitions of numbers from 0 to $n-1 in blocks of $k.
#
# Permutations are generated as arrayrefs, and undef is returned
# when the iterator is exhausted.
sub indexes {
    my ($n, $k) = @_;
    my $max_i = $n-1;
    my @idxs = (-1, (0) x ($k-1));
    return sub {
        my $exhausted = 1;
        IDXS:
        for my $i (@idxs) {
            if ($i < $max_i) {
                ++$i;
                $exhausted = 0;
                last IDXS;
            }
            $i = 0;
        }
        return $exhausted ? undef : [ @idxs ];
    };
}

-- fxn


--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>


Reply via email to