Initializing an anonymous hash (repost)

N

Neil Shadrach

If I have 2 arrays @k and @v I can initialize a hash %h with
@h{@k}=@v;
If my next step is
push @a,\%h;
is there a neat way to skip creating %h and initialize an anonymous
hash for use in a line like
push @a, {};

( Apologies for reposting via Google but the original doesn't seem to
have made it off the in-house server )
 
B

Brian McCauley

If I have 2 arrays @k and @v I can initialize a hash %h with
@h{@k}=@v;
If my next step is
push @a,\%h;
is there a neat way to skip creating %h and initialize an anonymous
hash for use in a line like
push @a, {};

No. You can rearange the problem in various ways with do{} or map()
but there is nothing neat builting. If you just want neat (not fast)
you could, or course write a function:

sub anon_slice(\@\@) {
my %h;
my $keys = shift;
@h{@$keys} = @{shift()};
\%h;
}

push @a => anon_slice( @h => @v );

--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 
T

Tad McClellan

Neil Shadrach said:
If I have 2 arrays @k and @v I can initialize a hash %h with
@h{@k}=@v;
If my next step is
push @a,\%h;
is there a neat way to skip creating %h and initialize an anonymous
hash for use in a line like
push @a, {};


push @a, { map { $k[$_], $v[$_] } 0 .. $#k };
 
U

Uri Guttman

NS> If I have 2 arrays @k and @v I can initialize a hash %h with
NS> @h{@k}=@v;
NS> If my next step is
NS> push @a,\%h;
NS> is there a neat way to skip creating %h and initialize an anonymous
NS> hash for use in a line like
NS> push @a, {};

besides the other two answers, i have done this. it works if you can
allow destruction of one of the arrays:

push( @a, { map { shift @k, $_ } @v } ) ;

you can destroy @v instead of @k:

push( @a, { map { $_, shift @v } @k } ) ;

either way should be faster then the others but benchmark to be sure.

uri
 
C

ctcgag

If I have 2 arrays @k and @v I can initialize a hash %h with
@h{@k}=@v;
If my next step is
push @a,\%h;
is there a neat way to skip creating %h and initialize an anonymous
hash for use in a line like
push @a, {};

Autovivify the hash in place.

use Data::Dumper;
my @a=({},{});
my @k=1..6;
my @v = map $_*$_, 1..6;
warn "Ugly, but works";
@{$a[@a]}{@k}=@v;
print Dumper(\@a);
__END__
Ugly, but works at - line 5.
$VAR1 = [
{},
{},
{
'6' => 36,
'4' => 16,
'1' => 1,
'3' => 9,
'2' => 4,
'5' => 25
}
];


Xho
 
B

Brad Baxter

(e-mail address removed) wrote in message
warn "Ugly, but works";

You're being too modest.
@{$a[@a]}{@k}=@v;

If I rework my original problem to be a little closer to your solution
:)

I wanted to eliminate %h from
@h{@k}=@v; $a[@a]=\%h;

I can just about convince myself that I understand if I allow the
pseudo-step of dereferencing both sides of the second statement as
arrays and then substitute in the first
@{$a[@a]}=@h; # ok I know I couldn't actually use @h like that - I did
say 'just about'

I'm not going to offer to stand up and jsutify that at a perl
conference though.

I'm not sure that describes it well. I'm not sure this does either. :)
But ...

o scalar @a is always just beyond the end of the array, so
o assigning to $a[@a] is essentially the same as push @a, ...
o you said, "If my next step is push @a,\%h;", so
o @{$a[@a]}{@k}=@v is autovivifying an anonymous hash at element $a[@a]
just as @h{@k}=@v would autovivify %h if it didn't exist before (and
strictures didn't block it).

Regards,

Brad
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,043
Latest member
CannalabsCBDReview

Latest Threads

Top