List Info

Thread: Re: Transforming a list into a hash of arrays




Re: Transforming a list into a hash of arrays
country flaguser name
United States
2007-02-07 21:01:31
--- In perl-beginner@yahoogroups.com, Rob Biedenharn
<Rob...> wrote:
>
> On Feb 7, 2007, at 7:36 PM, jslay77 wrote:
> > --- In perl-beginner@yahoogroups.com, Rob
Biedenharn <Rob> wrote:
> >> On Feb 7, 2007, at 10:58 AM, jslay77 wrote:
> >>> I hope this is the appropriate forum to
ask this question.
> >>>
> >>> assume I have a list like this:
> >>>
> >>> input = ('1', 'hostname1', '1',
'hostname2', '1', 'hostname3', '2',
> >>> 'hostname10', '2', 'hostname11', '3',
'hostname12');
> >>>
> >>> I want to turn this list into a hash of
anonymous arrays...something
> >>> like this I guess.
> >>>
> >>> %hash = (
> >>> '1' => ['hostname1', 'hostname2',
'hostname3'],
> >>> '2' => ['hostname10', 'hostname11'],
> >>> '3' => ['hostname12'],
> >>> );
> >>>
> >>>
> >>> 
> >>>
> >>> I hope I explained that appropriately.
> >>> regards,
> >>> J
> >>
> >> Why don't you post some code showing your
attempt and then we can
> >> help you if it doesn't do what you expect? 
Here's a hint, to
> >> initialize a hash element with an empty array
if it doesn't already
> >> have a value, you can do this:
> >>
> >>          $hash{$key} ||= [];
> >>
> >> I made a subroutine "array_to_hash"
taking a list of values and
> >> returning a hash.  My little script also used
> >> List::MoreUtils::natatime to get the pairs
from the array, but that's
> >> not the only way.  I also used Data:umper to
produce the output to
> >> visually check the result like this:
> >>
> >>
> >> input = ('1', 'hostname1', '1',
'hostname2', '1', 'hostname3', '2',
> >>            'hostname10', '2', 'hostname11',
'3', 'hostname12');
> >>
> >> my %hash = array_to_hash input;
> >>
> >> print Data:umper-&g
t;Dump([input, %hash], [qw(*input *hash)]);
> >>
> >>
> >> -Rob
> >>
> >> Rob Biedenharn		http://agileconsultingl
lc.com
> >> Rob
> >>
> >
> > Rob,
> >
> > Thanks for the quick response...and your
$hash{$key} ||=[] hint 
> >
> > I actually got around this whole thing by
retrieving my data  
> > differently from DBD::Oracle,
> > however I was still intrigued at the problem...I
believe I figured  
> > it out with your help.
> >
> > This does what I was looking for, however would
there be a better way?
> >
> > input = ('1', 'hostname1', '1', 'hostname2', '1',
'hostname3',  
> > '2', 'hostname10', '2',
> > 'hostname11', '3', 'hostname12');
> > my %hash;
> >
> > my %seen;
> You don't need this...
> 
> > my $key;
> You haven't used this...
> 
> But you don't initialize $i (which tells me that you
aren't using the  
> -w option)
> 
> > for (input; $i <= $#input; $i += 2) {
> Should be < not <=, but you get lucky since
you're incrementing by 2
> >     if (! $seen{$input[$i]}++ ) {
> >         $hash{$input[$i]} ||= ["$input[$i +
1]"];
> Unless you mean to stringify the values, you don't need
the quotes  
> just like you don't need them in the push.
> >     } else {
> >         push {$hash{$input[$i]}}, $input[$i + 1];
> >         next;
> >     }
> > }
> 
> Simplifying and you get (after really using the hint

> for (my $i = 0; $i < $#input; $i += 2) {
>      push {$hash{$input[$i]} ||= []},  $input[$i +
1];
> }
> 
> > foreach (sort keys %hash) {
> >     print "$_ --> {$hash{$_}}n";
> > }
> 
> And for completeness now that you've done your version.
 Here's mine:
> 
> #!/usr/bin/env perl -w
> use List::MoreUtils qw(natatime);
> use Data:umper;
> 
> sub array_to_hash {
>      my args = _;
>      my %hash;
> 
>      my $iter = natatime 2, args;
>      while (my ($key, $val) = $iter->()) {
>          $hash{$key} ||= [];
>          push {$hash{$key}}, $val;
>      }
>      return %hash;
> }
> 
> input = ('1', 'hostname1', '1', 'hostname2', '1',
'hostname3', '2',
>            'hostname10', '2', 'hostname11', '3',
'hostname12');
> my %hash = array_to_hash input;
> 
> print Data:umper-&g
t;Dump([input, %hash], [qw(*input *hash)]);
> 
> __END__
> 
> I could have (should have) made the loop body be the
single line:
>          push {$hash{$key} ||= []}, $val;
> 
> I hope that make sense.  The Data:umper
library is quite handy to  
> do quick views of data structures when they grow beyond
simple arrays  
> and hashes.  You might want to check out
List::MoreUtils (and  
> List::Util) for a number of useful manipulations of
lists (aka, arrays).
> 
> -Rob
> 
> Rob Biedenharn		http://agileconsultingl
lc.com
> Rob...
>


Awesome thanks for the corrections.  I posted that as soon
as it worked, and forgot to 
take some stuff out, and double check it. 

I appreciate the help!




Unsubscribing info is here: h
ttp://help.yahoo.com/help/us/groups/groups-32.html 
Yahoo! Groups Links

<*> To visit your group on the web, go to:
    http://g
roups.yahoo.com/group/perl-beginner/

<*> Your email settings:
    Individual Email | Traditional

<*> To change settings online go to:
    http
://groups.yahoo.com/group/perl-beginner/join
    (Yahoo! ID required)

<*> To change settings via email:
    mailto:perl-beginner-digest@yahoogroups.com 
    mailto:perl-beginner-fullfeatured@yahoogroups.com

<*> To unsubscribe from this group, send an email to:
    perl-beginner-unsubscribe@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
    http://docs.yahoo.c
om/info/terms/
 

[1]

about | contact  Other archives ( Real Estate discussion Medical topics )