Re: use array for hash-keys without loop
by almut (Canon) on Mar 11, 2010 at 12:15 UTC
|
#!/usr/bin/perl -l
my @a = qw(foo bar baz);
my %h;
@h{@a} = (1, 42, 99);
use Data::Dumper;
print Dumper \%h;
print "@h{@a}";
__END__
$VAR1 = {
'bar' => 42,
'baz' => 99,
'foo' => 1
};
1 42 99
| [reply] [d/l] |
Re: use array for hash-keys without loop
by cdarke (Prior) on Mar 11, 2010 at 12:51 UTC
|
my %hash; # Note: you cannot use 'my' on a slice
@hash{@a} = (0) x @a; # Initialise values to zero
@hash{@a} = undef; # No values
@hash{@a} = @b; # Take values from @b
| [reply] [d/l] |
|
|
$ perl -le'
use Data::Dumper;
my @a = "A" .. "D";
my %hash;
$hash{@a} = (0) x @a;
print Dumper \%hash;
'
$VAR1 = {
'4' => '0000'
};
Oops!
| [reply] [d/l] |
|
|
| [reply] [d/l] [select] |
|
|
Re: use array for hash-keys without loop
by toolic (Bishop) on Mar 11, 2010 at 15:04 UTC
|
| [reply] |
Re: use array for hash-keys without loop
by ikegami (Patriarch) on Mar 11, 2010 at 15:57 UTC
|
Impossible. You're asking to do something that's the very definition of looping without using a loop. What do you actually want?
my $val = Dive(\%b, map \$_, @a);
DiveVal(\%b, map \$_, @a)= $val;
Check out Data::Diver.
my $val = Dive(\%b, map \$_, @a);
DiveVal(\%b, map \$_, @a) = $val;
If @a contains no numbers, you can omit map \$_,.
my $val = Dive(\%b, @a);
DiveVal(\%b, @a) = $val;
Update: I thought you had $b{$a[0], $a[1], $a[2]}. Using a slice is definitely the cleanest solution. You'd still be looping, though.
| [reply] [d/l] [select] |
|
|
my @a = qw(foo bar baz);
my @b = (1, 42, 99);
# unwanted (considered too clumsy):
for my $i (0..$#a) {
$h{$a[$i]} = $b[$i];
}
# or
$h{$a[0]} = 1;
$h{$a[1]} = 42;
$h{$a[2]} = 99;
# or
($h{$a[0]}, $h{$a[1]}, $h{$a[2]}) = (1, 42, 99);
# wanted:
@h{@a} = @b;
@h{@a} = (1, 42, 99);
They don't particularly care about the internal implementation, i.e. that something behind the scenes of course will have to do the looping... At least, that's my guess.
| [reply] [d/l] |
|
|
It's often about perceived performance, I believe.
Sure, it's a clarity question here. What does that have to do with avoiding loops? I'd take
$b{$_}=1 for @a;
over
@b{@a} = (1)x@a;
even though the other might be considered to have no loop. (It has three while the first has two.)
Actually, I'd take the following since it incorporates the my:
my %b = map { $_ => 1 } @a;
| [reply] [d/l] [select] |
|
|
Impossible. You're asking to do something that's the very definition of looping without using a loop. What do you actually want?
At university I learned that loops can be replaced by recursivity. So the simple code below fulfills the requirements of the OP
(one line, no loop) ... but maybe isn't what he wants. ;-)
However this statement stems from a course of theoretical computer science. Don't use the code below in a productive environment.
It is slower and takes much more resources than the other, straightforward solutions presented in this thread!
You have been warned! Rata
use strict;
use warnings;
my @x = qw ( a b c d e ff ggg hhhh iiii );
my %y;
# Tata!!! Here comes the requested line of code:
noLoop(); sub noLoop { $y{pop(@x)} = 1; noLoop() if (scalar(@x)); } #
+ btw.: using global vars in subs is usually bad style ;-)
print keys(%y), "\n";
exit 0;
| [reply] [d/l] |
|
|
my %y; $y{shift(@x)} = 1 while @x;
or the non-destructive
my %y = map { $_ => 1 } @x;
| [reply] [d/l] [select] |
Re: use array for hash-keys without loop
by Ratazong (Monsignor) on Mar 11, 2010 at 12:20 UTC
|
| [reply] |
Re: use array for hash-keys without loop
by Anonymous Monk on Mar 11, 2010 at 21:14 UTC
|
use List::MoreUtils qw/mesh/;
my %b = mesh @a, @c;
| [reply] [d/l] |
Re: use array for hash-keys without loop
by Anonymous Monk on Mar 11, 2010 at 12:56 UTC
|
Why don't you want to use a loop? | [reply] |
Re: use array for hash-keys without loop
by Anonymous Monk on Mar 11, 2010 at 16:17 UTC
|
@a=qw(a b c d);
@b{@a}=(1,2,3,4);
foreach $key (keys %b) {
print"$key => $b{$key}\n";
}
| [reply] |