Merging/Joining AoA

Discussion in 'Perl Misc' started by Vishal G, Apr 22, 2008.

  1. Vishal G

    Vishal G Guest

    Hi Guys,

    I have a little complicated problem...

    I have two arrays

    @a = ( ['id', 'name', 'age'],
    ['1', 'Fred', '24'],
    ['2', 'Frank', '42'],
    );

    @b = ( ['id', 'sex'],
    ['1', 'm' ],
    ['2', 'm'],
    );

    I want to join these two AoA, based on id, so the resulting array will
    look like this

    @c = ( ['id', 'name', 'age', 'sex'],
    ['1', 'Fred', '24', 'm' ],
    ['2', 'Frank', '42', 'm'],
    );

    Any Ideas?

    Thanks in advance.
     
    Vishal G, Apr 22, 2008
    #1
    1. Advertising

  2. Vishal G

    Ben Bullock Guest

    On Apr 22, 3:35 pm, Vishal G <> wrote:
    > Hi Guys,
    >
    > I have a little complicated problem...
    >
    > I have two arrays
    >
    > @a = ( ['id', 'name', 'age'],
    > ['1', 'Fred', '24'],
    > ['2', 'Frank', '42'],
    > );
    >
    > @b = ( ['id', 'sex'],
    > ['1', 'm' ],
    > ['2', 'm'],
    > );
    >
    > I want to join these two AoA, based on id, so the resulting array will
    > look like this
    >
    > @c = ( ['id', 'name', 'age', 'sex'],
    > ['1', 'Fred', '24', 'm' ],
    > ['2', 'Frank', '42', 'm'],
    > );
    >
    > Any Ideas?


    my %akeys;
    @akeys{map $$_[0],@a} = @a;
    my %bkeys;
    @bkeys{map $$_[0],@b} = @b;
    my @c;
    for (sort keys %akeys) {
    if ($bkeys{$_}) {
    push @c, [@{$akeys{$_}},@{$bkeys{$_}}[1..$#{$bkeys{$_}}]];
    }
    }
    for (@c) {
    print "[",join (", ",@$_),"]\n";
    }
     
    Ben Bullock, Apr 22, 2008
    #2
    1. Advertising

  3. Vishal G

    Matija Papec Guest

    Vishal G wrote:
    > I have a little complicated problem...
    >
    > I have two arrays
    >
    > @a = ( ['id', 'name', 'age'],
    > ['1', 'Fred', '24'],
    > ['2', 'Frank', '42'],
    > );
    >
    > @b = ( ['id', 'sex'],
    > ['1', 'm' ],
    > ['2', 'm'],
    > );
    >
    > I want to join these two AoA, based on id, so the resulting array will
    > look like this
    >
    > @c = ( ['id', 'name', 'age', 'sex'],
    > ['1', 'Fred', '24', 'm' ],
    > ['2', 'Frank', '42', 'm'],
    > );


    Assuming that both @a and @b have same size and same id order,

    for my $i (0 .. $#a) {
    my $at = $a[$i];
    my $bt = $b[$i];
    push @$at, @$bt[1 .. $#$bt];
    }
    use Data::Dumper;
    print Dumper \@a;
     
    Matija Papec, Apr 22, 2008
    #3
  4. In <<>>
    schrieb Ben Bullock...

    > [...]
    > my @c;
    > for (sort keys %akeys) {
    > [...]
    > }
    > for (@c) {
    > print "[",join (", ",@$_),"]\n";
    > }


    Prints [1, Fred, 24, m]
    [2, Frank, 42, m]
    [id, name, age, sex]

    Take care of the 'sort' ;-)


    Alternatively, if you want to take care of the IDs of /both/ arrays,
    you could write:


    #!perl.exe -w # well, on Windows...
    use strict; # always 'use' this one!

    my @a = ( ['id', 'name', 'age' ], # just our data...
    ['2', 'Frank', '42' ],
    ['1', 'Fred', '24' ],
    ['3', 'Pat', '36' ],
    );
    my @b = ( ['id', 'sex' ], # ...to deal with
    ['1', 'm' ],
    ['2', 'm' ],
    ['4', '??' ],
    );

    my @afields = @{ shift @a }; # get rid of field names,
    my @bfields = @{ shift @b }; shift @bfields; # keeping them at hand
    my %a = map {$_->[0], $_} @a; # now we can refer to the...
    my %b = map {shift @{$_}, $_} @b; # ...data by their IDs

    my %seen; # just to avoid duplicates
    my @c = ( [ @afields, @bfields ], # field names come first
    map { [ $a{$_} ? @{$a{$_}} : ($_, ('') x $#afields),
    $b{$_} ? @{$b{$_}} : ( ('') x @bfields )
    ]
    } sort grep { $seen{$_}++ ? 0 : $_ }
    keys (%a), keys (%b)
    );


    ....gives

    ['id', 'name', 'age', 'sex']
    ['1', 'Fred', '24', 'm' ]
    ['2', 'Frank', '42', 'm' ]
    ['3', 'Pat', '36', '' ]
    ['4', '', '', '??' ]



    mfg, Hartmut


    --
    ------------------------------------------------
    Hartmut Camphausen h.camp[bei]textix[punkt]de
     
    Hartmut Camphausen, Apr 22, 2008
    #4
  5. On Apr 22, 2:35 am, Vishal G <> wrote:
    > Hi Guys,
    >
    > I have a little complicated problem...
    >
    > I have two arrays
    >
    > @a = ( ['id', 'name', 'age'],
    >            ['1', 'Fred', '24'],
    >            ['2', 'Frank', '42'],
    >          );
    >
    > @b = ( ['id', 'sex'],
    >            ['1', 'm' ],
    >            ['2', 'm'],
    >          );
    >
    > I want to join these two AoA, based on id, so the resulting array will
    > look like this
    >
    > @c = ( ['id', 'name', 'age', 'sex'],
    >            ['1', 'Fred', '24', 'm' ],
    >            ['2', 'Frank', '42', 'm'],
    >          );
    >
    > Any Ideas?


    I'm not sure how much control you have over the structure of the data,
    but it seems to me that you would be better served if the data were
    stored in hashes to begin with:

    use strict; use warnings;
    use Data::Dumper;

    my %people = (
    1 => { name => 'Fred', age => 24 },
    2 => { name => 'Frank', age => 42 },
    );

    my %gender = (
    1 => { sex => 'm' },
    2 => { sex => 'm' },
    );

    ...then it's a simple matter to combine the two structures, keyed by
    the id.

    for my $id ( keys %people ) {
    $people{$id}{sex} = $gender{$id}{sex};
    }



    print Dumper( \%people ), "\n";
     
    nolo contendere, Apr 22, 2008
    #5
  6. Vishal G

    Ben Bullock Guest

    On Tue, 22 Apr 2008 16:24:19 +0200, Hartmut Camphausen wrote:

    > Prints [1, Fred, 24, m]
    > [2, Frank, 42, m]
    > [id, name, age, sex]


    Yes, I know. So what?

    > Take care of the 'sort' ;-)


    I don't care about the order of these results. The original poster can
    figure out all the details if he wants to.

    > Alternatively, if you want to take care of the IDs of /both/ arrays, you
    > could write:


    Yes, but I have no way to really guess in detail what the original poster
    wanted, so why spend a lot of time trying to cover every possibility? I
    wrote that initial answer in only a minute or two, and I think it's good
    enough to get the poster on track towards an answer.
     
    Ben Bullock, Apr 22, 2008
    #6
  7. On Apr 22, 11:11 am, nolo contendere <> wrote:
    > On Apr 22, 2:35 am, Vishal G <> wrote:
    >
    >
    >
    > > Hi Guys,

    >
    > > I have a little complicated problem...

    >
    > > I have two arrays

    >
    > > @a = ( ['id', 'name', 'age'],
    > >            ['1', 'Fred', '24'],
    > >            ['2', 'Frank', '42'],
    > >          );

    >
    > > @b = ( ['id', 'sex'],
    > >            ['1', 'm' ],
    > >            ['2', 'm'],
    > >          );

    >
    > > I want to join these two AoA, based on id, so the resulting array will
    > > look like this

    >
    > > @c = ( ['id', 'name', 'age', 'sex'],
    > >            ['1', 'Fred', '24', 'm' ],
    > >            ['2', 'Frank', '42', 'm'],
    > >          );

    >
    > > Any Ideas?

    >
    > I'm not sure how much control you have over the structure of the data,
    > but it seems to me that you would be better served if the data were
    > stored in hashes to begin with:
    >
    > use strict; use warnings;
    > use Data::Dumper;
    >
    > my %people = (
    >   1 => { name => 'Fred',  age => 24 },
    >   2 => { name => 'Frank', age => 42 },
    > );
    >
    > my %gender = (
    >   1 => { sex => 'm' },
    >   2 => { sex => 'm' },
    > );
    >
    > ...then it's a simple matter to combine the two structures, keyed by
    > the id.
    >
    > for my $id ( keys %people ) {
    >     $people{$id}{sex} = $gender{$id}{sex};
    >
    > }
    >
    > print Dumper( \%people ), "\n";


    One more thing, are you certain that you wanted to quote the age
    values in your data? in most cases perl is smart enough to dwym, but
    for clarity i think it would be better to leave them as numbers rather
    than strings.
     
    nolo contendere, Apr 22, 2008
    #7
  8. Vishal G

    Guest

    nolo contendere <> wrote:

    > I'm not sure how much control you have over the structure of the data,
    > but it seems to me that you would be better served if the data were
    > stored in hashes to begin with:


    If the person needs to know how to put in a screw, why tell him he
    would be better served by using nails and a hammer?

    A quote from Stephen King (viewable at
    http://www.nsftools.com/blog/blog-03-2006.htm) comes to mind:

    "I want to suggest to you that to write to the best of your abilities,
    it behooves you to construct your own toolbox and then build up enough
    muscle so you can carry it with you. Then, instead of looking at a
    hard job and getting discouraged, you will perhaps seize the correct
    tool and get immediately to work."

    In the real world, there are lots of situations in which you're likely
    to get data in an array of arrays. For example if you take data from a
    "Range" in an Excel spreadsheet, you'll get it back as an array of
    arrays, just like the original poster's problem. Instead of looking at
    a hard job and getting discouraged, I'd suggest you think about
    seizing the correct tool and getting immediately to work.
     
    , Apr 23, 2008
    #8
  9. Vishal G

    Ted Zlatanov Guest

    On Tue, 22 Apr 2008 21:55:03 -0700 Keith Keller <-francisco.ca.us> wrote:

    KK> use Shining;

    KK> my $shine=Shining->new;
    KK> $shine->enterRoom(237);
    KK> $shine->avoid('Dad');
    KK> $shine->call('cook');
    KK> $shine->REDRUM;
    KK> $shine->escape('hedgeMaze','snowmobile');

    I think you forgot to include the POD:

    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
    All work and no play makes Jack a dull boy
     
    Ted Zlatanov, Apr 23, 2008
    #9
  10. On Apr 22, 11:49 pm, wrote:
    > nolo contendere <> wrote:
    > > I'm not sure how much control you have over the structure of the data,
    > > but it seems to me that you would be better served if the data were
    > > stored in hashes to begin with:

    >
    > If the person needs to know how to put in a screw, why tell him he
    > would be better served by using nails and a hammer?



    huh? i began my suggestion with the caveat that this would be relevant
    if the OP had the control to choose the data structures in which he
    housed his data. to follow up on your analogy, if the person needs to
    know how to build a house, and is scratching his head wondering how to
    do it with only screws and a screwdriver, yes, i could help him by
    telling him how to go about it.

    or, i can point out that there is a tool shed around the corner of
    which he is unaware, and then proceed to pick out more appropriate
    tools that he can use to better build his house.

    here's another analogy. if he asked, how do i add the following?
    <<END_WORD_PROBLEM;

    i want to add three 6's and six 4's using addition. sure, you could
    say: well, first compute the sum of the three 6's, like so--
    6 + 6 + 6 = 18.
    then, compute the sum of six 4's, like so--
    4 + 4 + 4 + 4 + 4 + 4 = 24.
    finally, add the two sums together.
    18 + 24 = 42.
    END_WORD_PROBLEM

    Or, I could make life a whole lot easier by suggesting:
    just do: (3 x 6) + (6 x 4) = 42.

    what's wrong with that? at the very worst, if there are restrictions
    in place that prohibit him from using multiplication for this
    particular problem, he is at least aware that there is a better
    solution for similar problems in the future, when such restrictions
    may may be lifted, or not even exist at all.

    ...or did you just want an excuse to post that quote by Steven
    King? ;-).
     
    nolo contendere, Apr 23, 2008
    #10
  11. Vishal G

    Ben Bullock Guest

    On Wed, 23 Apr 2008 07:46:35 -0700, nolo contendere wrote:

    > On Apr 22, 11:49 pm, wrote:


    >> If the person needs to know how to put in a screw, why tell him he
    >> would be better served by using nails and a hammer?

    >
    >
    > huh? i began my suggestion with the caveat that this would be relevant
    > if the OP had the control to choose the data structures in which he
    > housed his data. to follow up on your analogy, if the person needs to
    > know how to build a house, and is scratching his head wondering how to
    > do it with only screws and a screwdriver, yes, i could help him by
    > telling him how to go about it.


    Well, I'm sorry to offend you.

    > ...or did you just want an excuse to post that quote by Steven King?
    > ;-).


    No, I think it was the correct time to post that quote. Or maybe a more
    relevant quote would be something about how if you endlessly try to
    finesse things, you'll never actually get the job done. Perl programmers
    should know how to deal with awkward data formats like the original
    poster's, because these do occur in practice, and they may be unavoidable
    for one reason or another.
     
    Ben Bullock, Apr 23, 2008
    #11
  12. <> wrote:
    > nolo contendere <> wrote:
    >
    >> I'm not sure how much control you have over the structure of the data,
    >> but it seems to me that you would be better served if the data were
    >> stored in hashes to begin with:

    >
    > If the person needs to know how to put in a screw, why tell him he
    > would be better served by using nails and a hammer?



    Errr, because he would be better served, of course.


    Q: I need to put a lot of screws in to hold the shingles on the roof.
    Can anyone suggest a good power screwdriver?

    A: You would be better served by using nails and a nail gun.


    If you use screws it will take you 2 days to finish instead of 1 day.

    Even worse, when you need to maintain your roof, it will take you
    4 days to remove the old one instead of 1 day if you had used nails.



    Choice of an approriate data structure is very important in designing
    a software solution. (It made this task into a one-liner.)

    If you don't have a choice of data structure, then you must
    bite the bullet and write 10 or 20 lines of code.

    nolo gave an appropriate predicate to his advice.

    Seems clear enough that the advice should be skipped if the predicate
    is not true...


    --
    Tad McClellan
    email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"
     
    Tad J McClellan, Apr 24, 2008
    #12
  13. Vishal G

    Ben Bullock Guest

    Tad J McClellan <> wrote:

    >> If the person needs to know how to put in a screw, why tell him he
    >> would be better served by using nails and a hammer?

    >
    >
    > Errr, because he would be better served, of course.
    >
    >
    > Q: I need to put a lot of screws in to hold the shingles on the roof.
    > Can anyone suggest a good power screwdriver?
    >
    > A: You would be better served by using nails and a nail gun.


    Since I have no idea what the original poster's task was, why
    speculate about it?

    > Choice of an approriate data structure is very important in designing
    > a software solution. (It made this task into a one-liner.)
    >
    > If you don't have a choice of data structure, then you must
    > bite the bullet and write 10 or 20 lines of code.


    My original solution had ten lines of code, it's true. But if you want
    to reduce the lines of code, it's perfectly possible:

    my %ak = (map{$$_[0],$_} @a);
    my %bk = (map{$$_[0],$_} @b);
    for (sort keys %ak) {my $v=$bk{$_}; push @c, [@{$ak{$_}}, @$v[1..$#$v]] if $v}
    unshift @c, pop @c; # Just for Harmut Camphausen

    That has the disadvantage of being less clear to read but it does
    exactly the same thing.

    If I was doing this for real I'd be much more worried about
    problems such as empty values in the first column of the array, or
    duplicate IDs in @a, or what to do with values which are in @a but not
    in @b or vice-versa, than I would be about turning the whole thing into
    a hash keyed by the values on the first line. That could just as
    easily make other parts of the program more complicated, and it seems
    to me that Perl programmers should be able to write code to deal with
    arrays of arrays without getting confused, or write a regular
    expression to match single quoted strings.

    So I'm not sure what the point of the original advice was. To me it's
    just confusing the issue.
     
    Ben Bullock, Apr 24, 2008
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Awah Teh

    SubQuerying Vs Joining

    Awah Teh, Oct 29, 2003, in forum: ASP .Net
    Replies:
    2
    Views:
    804
    Rich Dillon
    Oct 30, 2003
  2. Stuart
    Replies:
    3
    Views:
    465
    Joe Smith
    Aug 19, 2004
  3. =?Utf-8?B?TWlrZSBNb29yZQ==?=

    joining tables or view

    =?Utf-8?B?TWlrZSBNb29yZQ==?=, Jul 7, 2005, in forum: ASP .Net
    Replies:
    0
    Views:
    363
    =?Utf-8?B?TWlrZSBNb29yZQ==?=
    Jul 7, 2005
  4. Chris McMahon

    construct AoA with REXML XPath?

    Chris McMahon, Mar 15, 2006, in forum: Ruby
    Replies:
    3
    Views:
    127
    William James
    Mar 16, 2006
  5. Gundala Viswanath

    Problem with Eval in Constructing AoA

    Gundala Viswanath, Sep 4, 2008, in forum: Perl Misc
    Replies:
    2
    Views:
    108
    Eric Pozharski
    Sep 4, 2008
Loading...

Share This Page