Joining 2 arrays into hashes

E

Edward Wijaya

Hi,

I have these two arrays

@array1 = qw (a b c d);
@array2 = (1,2,3,4);

If I want to create a hash from this two
arrays so that elements of @array1 becomes
key and elements of @array2 as its
value.

How can I do it?
Thanks so much for your time.

Regards
Edward WIJAYA
SINGAPORE
 
G

Gunnar Hjalmarsson

Edward said:
I have these two arrays

@array1 = qw (a b c d);
@array2 = (1,2,3,4);

If I want to create a hash from this two arrays so that elements of
@array1 becomes key and elements of @array2 as its value.

How can I do it?

Through a hash slice:

my %hash;
@hash{ @array1 } = @array2;
 
J

John Bokma

Gunnar said:
Through a hash slice:

my %hash;
@hash{ @array1 } = @array2;

When I see this construction I always wonder why:

my @hash{ @array1 } = @array2;

doesn't work (or didn't, maybe it's fixed). Is there any reason why this
should not work, that's not obvious to me?
 
G

Gunnar Hjalmarsson

John said:
When I see this construction I always wonder why:

my @hash{ @array1 } = @array2;

doesn't work (or didn't, maybe it's fixed). Is there any reason why
this should not work, that's not obvious to me?

I suppose it's simply because a named hash must be declared using the
'%' character. One rational for it may be to prevent typos.

If you disable strictures and skip the declaration (not advisable),
you can do just

@hash{ @array1 } = @array2;
 
E

Eric Bohlman

When I see this construction I always wonder why:

my @hash{ @array1 } = @array2;

doesn't work (or didn't, maybe it's fixed). Is there any reason why this
should not work, that's not obvious to me?

my declares variables. A hash slice isn't a variable (nor is an array
slice, an array element, or a hash entry). You can't do

my $array[1]='foo';

either.
 
A

Anno Siegel

Gunnar Hjalmarsson said:
I suppose it's simply because a named hash must be declared using the
'%' character. One rational for it may be to prevent typos.

If you disable strictures and skip the declaration (not advisable),
you can do just

@hash{ @array1 } = @array2;

If you're happy with a package variable you *can* declare it in one
statement:

@{ \ our %hash}{ @array1} = @array2;

Formally this also works with a lexical:

@{ \ my %hash}{ @array1} = @array2;

....but it's completely useless because the lexical can't leave the
tiny block it is declared in.

Anno
 
J

John Bokma

Gunnar said:
I suppose it's simply because a named hash must be declared using the
'%' character. One rational for it may be to prevent typos.

Uhm, I think the {} clearly shows what the intentions are? I mean, I can
do my %array = @array; (And I am happy with that)
If you disable strictures and skip the declaration (not advisable),
you can do just

@hash{ @array1 } = @array2;

Yeah, but I want the my :-D.
 
J

John Bokma

Eric said:
my declares variables.

Yup, and why can't the above construct not declare a hash and use it?
It's not really that different from other perl constructs.
A hash slice isn't a variable (nor is an array
slice, an array element, or a hash entry). You can't do

my $array[1]='foo';

There is no reason why it can't create the @array and put 'foo' at index
1. It's not that unclear from other magic Perl uses.
 
M

Matija Papec

Uhm, I think the {} clearly shows what the intentions are? I mean, I can
do my %array = @array; (And I am happy with that)


Yeah, but I want the my :-D.

use strict;
@$_{qw/one two/} = (1,2) for \my %h;
use Data::Dumper; print Dumper %h;

but IMO, it's not worth the effort.
 
J

John Bokma

Matija said:
use strict;
@$_{qw/one two/} = (1,2) for \my %h;
use Data::Dumper; print Dumper %h;

Yeah, especially since I want to improve readability :-D.
 
C

Charles DeRykus

When I see this construction I always wonder why:

my @hash{ @array1 } = @array2;

doesn't work (or didn't, maybe it's fixed). Is there any reason why this
should not work, that's not obvious to me?

I always thought an interleave function would be useful (List::Util maybe?)

sub interleave(\@\@) { return $#{$_[0]} != $#{$_[1]} ? undef :
map { ($_[0]->[$_],$_[1]->[$_]) } 0..$#{$_[0]}; }


my %hash = interleave @array1,@array2;
 
J

John Bokma

Charles said:
I always thought an interleave function would be useful (List::Util maybe?)

sub interleave(\@\@) { return $#{$_[0]} != $#{$_[1]} ? undef :
map { ($_[0]->[$_],$_[1]->[$_]) } 0..$#{$_[0]}; }


my %hash = interleave @array1,@array2;

That is what @hash{@array1} = @array2; does unless I don't understand
what you mean. (Ok, with interleave you can make it a one liner :-D)
 
A

Anno Siegel

John Bokma said:
Charles said:
I always thought an interleave function would be useful (List::Util maybe?)

sub interleave(\@\@) { return $#{$_[0]} != $#{$_[1]} ? undef :
map { ($_[0]->[$_],$_[1]->[$_]) } 0..$#{$_[0]}; }


my %hash = interleave @array1,@array2;

That is what @hash{@array1} = @array2; does unless I don't understand
what you mean. (Ok, with interleave you can make it a one liner :-D)

....or interleave them on the fly:

my %hash = ( @array1, @array2)[ map { $_, @array1 + $_} 0 .. $#array1];

:)

Anno
 
C

ctcgag

Kevin Collins said:
Uhm, I think the {} clearly shows what the intentions are? I mean, I
can do my %array = @array; (And I am happy with that)

Yes, but think of it this way: you are defining a *slice* of a hash, not
(necessarily) the whole hash. Its the same reason you can't do:

my $var[2] = 'val';

You can't lexically scope only part of an array or a hash, you have to do
the whole thing.

But we aren't asking to lexically scope part of an array or hash, just to
be able to lexically scope an entire array or hash in the same statement
that initializes a portion of it. I don't see any fundamental reason it
wouldn't work, as far as I can tell it doesn't introduce any syntactic
ambiguity. It would just be a matter of adding a little more DWIM to the
language.

Xho
 
B

Ben Morrow

Quoth (e-mail address removed):
Kevin Collins said:
Uhm, I think the {} clearly shows what the intentions are? I mean, I
can do my %array = @array; (And I am happy with that)

Yes, but think of it this way: you are defining a *slice* of a hash, not
(necessarily) the whole hash. Its the same reason you can't do:

my $var[2] = 'val';

You can't lexically scope only part of an array or a hash, you have to do
the whole thing.

But we aren't asking to lexically scope part of an array or hash, just to
be able to lexically scope an entire array or hash in the same statement
that initializes a portion of it. I don't see any fundamental reason it
wouldn't work, as far as I can tell it doesn't introduce any syntactic
ambiguity. It would just be a matter of adding a little more DWIM to the
language.

Yes. However, it would be hard to implement given the current perl
parser: the subject of a my would have to have two semantic values: the
object that was being defined and the lvalue that was the return value
of the my (in this case, the whole array and the slice respectively).
This would be very messy to put into perly.y.

Ben
 
A

Anno Siegel

Kevin Collins said:
Uhm, I think the {} clearly shows what the intentions are? I mean, I
can do my %array = @array; (And I am happy with that)

Yes, but think of it this way: you are defining a *slice* of a hash, not
(necessarily) the whole hash. Its the same reason you can't do:

my $var[2] = 'val';

You can't lexically scope only part of an array or a hash, you have to do
the whole thing.

But we aren't asking to lexically scope part of an array or hash, just to
be able to lexically scope an entire array or hash in the same statement
that initializes a portion of it. I don't see any fundamental reason it
wouldn't work, as far as I can tell it doesn't introduce any syntactic
ambiguity. It would just be a matter of adding a little more DWIM to the
language.

my() already does some extra gymnastics to get the scope right in
"while ( my $x ... )" and similar. Perl has never suffered from much
concern for the lexer and its difficulties, but the additional stress
could (to coin a phrase) be the straw that breaks the camel's back.

It would also break the parallelism between local() and my() (in addition
to ways it is already broken). "local( @hash{ @list})" already has a
meaning, and it's not to localize %hash as a whole, the way my() would
have to work.

Anno
 
B

Brad Baxter

Kevin Collins said:
Uhm, I think the {} clearly shows what the intentions are? I mean, I
can do my %array = @array; (And I am happy with that)

Yes, but think of it this way: you are defining a *slice* of a hash, not
(necessarily) the whole hash. Its the same reason you can't do:

my $var[2] = 'val';

You can't lexically scope only part of an array or a hash, you have to do
the whole thing.

But we aren't asking to lexically scope part of an array or hash, just to
be able to lexically scope an entire array or hash in the same statement
that initializes a portion of it. I don't see any fundamental reason it
wouldn't work, as far as I can tell it doesn't introduce any syntactic
ambiguity. It would just be a matter of adding a little more DWIM to the
language.

my() already does some extra gymnastics to get the scope right in
"while ( my $x ... )" and similar. Perl has never suffered from much
concern for the lexer and its difficulties, but the additional stress
could (to coin a phrase) be the straw that breaks the camel's back.

It would also break the parallelism between local() and my() (in addition
to ways it is already broken). "local( @hash{ @list})" already has a
meaning, and it's not to localize %hash as a whole, the way my() would
have to work.

Anno

I think the following thread in P5P is related to this topic, in that it
allows for this:

my $var->[2] = 'val';

which admittedly is slightly different. Whether or not it also allows for

my $var[2] = 'val';

I'm not sure, but it doesn't appear so.


http://groups.google.com/[email protected]


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
474,264
Messages
2,571,065
Members
48,770
Latest member
ElysaD

Latest Threads

Top