converting a hash where the value is a list of lists to just a list

Discussion in 'Perl Misc' started by Lynn, Sep 9, 2005.

  1. Lynn

    Lynn Guest

    Hi All,

    I have a hash where the values are a list of lists. What I would like to do
    is
    convert this to a hash where the value is just a reference to an array that
    contains
    the list of lists. Below is my attempt to convert this to what I want, the
    problem
    is that I am loosing some people in the process!

    use strict;
    use warnings;
    use Data::Dumper;
    my %people = (
    'hillrich' => [ [5308125], [2053628], [5312468], [5312492] ],
    'hsieh' => [ [5312182], [5312613], [5312517] ],
    'prakash' => [],
    'florencb' => [
    [1420688], [1420596], [5312242], [5306884], [5305217], [5248521],
    ],
    'x_shukl' => []
    );
    my %new_format_people=();
    foreach my $person(keys %people) {
    foreach my $item (@{ $people{$person} }) {
    for ( @$item) {
    push @{$new_format_people{$person}},$_;
    }
    }
    }

    print Dumper(\%new_format_people);

    output is:
    $VAR1 = {
    'hillrich' => [
    5308125,
    2053628,
    5312468,
    5312492
    ],
    'hsieh' => [
    5312182,
    5312613,
    5312517
    ],
    'florencb' => [
    1420688,
    1420596,
    5312242,
    5306884,
    5305217,
    5248521
    ]
    };

    I lost prakash and x_shukl in the conversion process. How can I keep these
    people
    in the new hash I am creating?

    Thanks

    Lynn
     
    Lynn, Sep 9, 2005
    #1
    1. Advertising

  2. Lynn

    Paul Lalli Guest

    Lynn wrote:

    > I have a hash where the values are a list of lists.


    It's important to get the terminology correct. The values are
    references to arrays of references to single-item arrays. (Contrary to
    the naming of the perllol perldoc, there is no such thing as a "list of
    lists").

    > What I would like to do is
    > convert this to a hash where the value is just a reference to an array that
    > contains the list of lists.


    It looks to me as though what you wanted to do is convert the hash so
    that the value is a reference to an array that contains all of the
    values of the "inner" arrays.

    > Below is my attempt to convert this to what I want, the problem
    > is that I am loosing some people in the process!
    >
    > use strict;
    > use warnings;
    > use Data::Dumper;
    > my %people = (
    > 'hillrich' => [ [5308125], [2053628], [5312468], [5312492] ],
    > 'hsieh' => [ [5312182], [5312613], [5312517] ],
    > 'prakash' => [],
    > 'florencb' => [
    > [1420688], [1420596], [5312242], [5306884], [5305217], [5248521],
    > ],
    > 'x_shukl' => []
    > );
    > my %new_format_people=();
    > foreach my $person(keys %people) {
    > foreach my $item (@{ $people{$person} }) {
    > for ( @$item) {
    > push @{$new_format_people{$person}},$_;


    You're only adding any values to the %new_format_people hash within the
    loop that goes through the existing list. If there are no values to
    iterate over, no value will be added to the new hash.

    > }
    > }
    > }


    > I lost prakash and x_shukl in the conversion process. How can I keep these
    > people in the new hash I am creating?


    I see two options. The least modification to your code would simply be
    to explicitly add an empty array reference before attempting to copy
    over the "inner" array values:

    $new_format_people{$person} = [ ]; #this goes before the innermost for
    loop

    Alternatively, you could replace both inner for loops with one map
    statement:
    $new_format_people{$person} = [ map { $_->[0] } @{$people{$person}} ];

    This creates a new entry in %new_format_people where the key is the
    current person and the value is an array ref consisting of all the
    values from "inner" arrays.

    To make it more general, in case any of your "inner" arrays ever have
    more than one element, replace $_->[0] with the entire array: @$_

    Hope this helps,
    Paul Lalli
     
    Paul Lalli, Sep 9, 2005
    #2
    1. Advertising

  3. Re: converting a hash where the value is a list of lists to justa list

    Lynn wrote:
    >
    > I have a hash where the values are a list of lists. What I would like to do
    > is convert this to a hash where the value is just a reference to an array
    > that contains the list of lists. Below is my attempt to convert this to what
    > I want, the problem is that I am loosing some people in the process!
    >
    > use strict;
    > use warnings;
    > use Data::Dumper;
    > my %people = (
    > 'hillrich' => [ [5308125], [2053628], [5312468], [5312492] ],
    > 'hsieh' => [ [5312182], [5312613], [5312517] ],
    > 'prakash' => [],
    > 'florencb' => [
    > [1420688], [1420596], [5312242], [5306884], [5305217], [5248521],
    > ],
    > 'x_shukl' => []
    > );
    > my %new_format_people=();
    > foreach my $person(keys %people) {
    > foreach my $item (@{ $people{$person} }) {
    > for ( @$item) {
    > push @{$new_format_people{$person}},$_;
    > }
    > }
    > }
    >
    > print Dumper(\%new_format_people);


    $ perl -e'
    use Data::Dumper;
    my %people = (
    hillrich => [ [5308125], [2053628], [5312468], [5312492] ],
    hsieh => [ [5312182], [5312613], [5312517] ],
    prakash => [],
    florencb => [ [1420688], [1420596], [5312242], [5306884], [5305217],
    [5248521], ],
    x_shukl => [],
    );
    my %new_format_people = %people;
    $_ = [ map ref() ? @$_ : $_, @$_ ] for values %new_format_people;
    print Dumper \%new_format_people;
    '
    $VAR1 = {
    'hillrich' => [
    5308125,
    2053628,
    5312468,
    5312492
    ],
    'hsieh' => [
    5312182,
    5312613,
    5312517
    ],
    'florencb' => [
    1420688,
    1420596,
    5312242,
    5306884,
    5305217,
    5248521
    ],
    'prakash' => [],
    'x_shukl' => []
    };




    John
    --
    use Perl;
    program
    fulfillment
     
    John W. Krahn, Sep 9, 2005
    #3
  4. Lynn

    Lynn Guest

    Hi Paul,

    Paul Lalli wrote:
    > Lynn wrote:
    >
    >> I have a hash where the values are a list of lists.

    >
    > It's important to get the terminology correct. The values are
    > references to arrays of references to single-item arrays. (Contrary
    > to the naming of the perllol perldoc, there is no such thing as a
    > "list of lists").


    Ok

    >
    >> What I would like to do is
    >> convert this to a hash where the value is just a reference to an
    >> array that contains the list of lists.

    >
    > It looks to me as though what you wanted to do is convert the hash so
    > that the value is a reference to an array that contains all of the
    > values of the "inner" arrays.


    yes, that is exactly what I wanted to do. Sorry for the confusion.
    >

    (snipped)
    >
    > You're only adding any values to the %new_format_people hash within
    > the loop that goes through the existing list. If there are no values
    > to iterate over, no value will be added to the new hash.


    I see that now. Thanks for pointing it out.

    >
    >> I lost prakash and x_shukl in the conversion process. How can I keep
    >> these people in the new hash I am creating?

    >
    > I see two options. The least modification to your code would simply
    > be to explicitly add an empty array reference before attempting to
    > copy over the "inner" array values:
    >
    > $new_format_people{$person} = [ ]; #this goes before the innermost
    > for loop
    >
    > Alternatively, you could replace both inner for loops with one map
    > statement:
    > $new_format_people{$person} = [ map { $_->[0] } @{$people{$person}} ];
    >
    > This creates a new entry in %new_format_people where the key is the
    > current person and the value is an array ref consisting of all the
    > values from "inner" arrays.


    This is exactly what I need :)

    > Hope this helps,


    Thanks for all of your help Paul! :)
     
    Lynn, Sep 9, 2005
    #4
  5. Lynn

    Lynn Guest

    Hi John,

    John W. Krahn wrote:
    > Lynn wrote:
    >>

    (my stuff snipped)

    >
    > $ perl -e'
    > use Data::Dumper;
    > my %people = (
    > hillrich => [ [5308125], [2053628], [5312468], [5312492] ],
    > hsieh => [ [5312182], [5312613], [5312517] ],
    > prakash => [],
    > florencb => [ [1420688], [1420596], [5312242], [5306884],
    > [5305217], [5248521], ],
    > x_shukl => [],
    > );
    > my %new_format_people = %people;
    > $_ = [ map ref() ? @$_ : $_, @$_ ] for values %new_format_people;
    > print Dumper \%new_format_people;


    Wow, I need to study this! Thanks a lot :)

    > John
     
    Lynn, Sep 9, 2005
    #5
  6. Lynn

    Anno Siegel Guest

    Lynn <> wrote in comp.lang.perl.misc:
    > Hi John,
    >
    > John W. Krahn wrote:
    > > Lynn wrote:
    > >>

    > (my stuff snipped)
    >
    > >
    > > $ perl -e'
    > > use Data::Dumper;
    > > my %people = (
    > > hillrich => [ [5308125], [2053628], [5312468], [5312492] ],
    > > hsieh => [ [5312182], [5312613], [5312517] ],
    > > prakash => [],
    > > florencb => [ [1420688], [1420596], [5312242], [5306884],
    > > [5305217], [5248521], ],
    > > x_shukl => [],
    > > );
    > > my %new_format_people = %people;
    > > $_ = [ map ref() ? @$_ : $_, @$_ ] for values %new_format_people;
    > > print Dumper \%new_format_people;

    >
    > Wow, I need to study this! Thanks a lot :)


    Here is a way to do it in place:

    for ( values %people ) {
    $_ = $_->[ 0] for @$_;
    }

    Anno
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
     
    Anno Siegel, Sep 12, 2005
    #6
    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. robin
    Replies:
    10
    Views:
    551
    Dave Hansen
    Apr 12, 2006
  2. =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==

    List of lists of lists of lists...

    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==, May 8, 2006, in forum: Python
    Replies:
    5
    Views:
    425
    =?UTF-8?B?w4FuZ2VsIEd1dGnDqXJyZXogUm9kcsOtZ3Vleg==
    May 15, 2006
  3. rp
    Replies:
    1
    Views:
    556
    red floyd
    Nov 10, 2011
  4. Une bévue
    Replies:
    5
    Views:
    155
    Une bévue
    Aug 10, 2006
  5. Replies:
    8
    Views:
    94
Loading...

Share This Page