Re: Simplifying for loop and applying multiple push function
by Roy Johnson (Monsignor) on Dec 14, 2005 at 20:53 UTC
|
You're not going to be able to do it sensibly in one line. You can get rid of the loop and do it in two statements, though:
push @one, values %hash;
push @two, keys %hash;
Caution: Contents may have been coded under pressure.
| [reply] [d/l] |
|
| [reply] [d/l] |
|
@one = values %hash;
@two = keys %hash;
Even though the net result is the same.
Just wanted to show another WTDI.
Update
Whoops, Roy Johnson is right, this is equivalent only in some circumstances.
| [reply] [d/l] |
|
| [reply] |
|
|
Re: Simplifying for loop and applying multiple push function
by davido (Cardinal) on Dec 14, 2005 at 21:16 UTC
|
Just because someone said it can't be done in one line, I had to try:
use warnings;
use strict;
my %hash = ( 1 => 'one' , 2 => 'two' , 3 => 'three' );
# Here is the one line!
my( @one ) = @hash{ my( @two ) = keys %hash };
# This line is just to demonstrate it worked.
print map { "$two[$_] => $one[$_]\n" } 0 .. $#two;
Turns out you can do it in one with a slice. Roy_Johnson's approach deserves a ++ though, since it is actually legible. :)
| [reply] [d/l] |
Re: Simplifying for loop and applying multiple push function
by BrowserUk (Patriarch) on Dec 14, 2005 at 22:24 UTC
|
@hash{ 'a'..'z' } = 1 .. 26;;
1 while ( $one[@one], $two[@two] ) = each %hash;;
print "@one\n@two";;
r a x d j y u k h g f t i e n v m s l c p q b z o
18 1 24 4 10 25 21 11 8 7 6 20 9 5 14 22 13 19 12 3 16 17 2 26 15
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [d/l] |
Re: Simplifying for loop and applying multiple push function
by GrandFather (Saint) on Dec 14, 2005 at 21:57 UTC
|
--$| ? push @one, $_ : push @two, $_ foreach %hash;
DWIM is Perl's answer to Gödel
| [reply] [d/l] |
|
push @{--$| ? \@one : \@two}, $_ for %hash;
P.S. Is there some unspoken mission to use --$| for everything?
| [reply] [d/l] [select] |
Re: Simplifying for loop and applying multiple push function
by GrandFather (Saint) on Dec 14, 2005 at 21:46 UTC
|
use strict;
use warnings;
my %hash = ( 1 => 'one' , 2 => 'two' , 3 => 'three' );
my (@one, @two);
(push @one , $hash{$_}), push @two, $_ foreach ( keys %hash );
print "@one\n@two";
Prints:
one three two
1 3 2
DWIM is Perl's answer to Gödel
| [reply] [d/l] [select] |
Re: Simplifying for loop and applying multiple push function
by GrandFather (Saint) on Dec 14, 2005 at 22:22 UTC
|
Benchmark time :)
Results:
Rate sneekyDuff BUK sneekyGF orig GF roy
+ VS davido
sneekyDuff 55138/s -- -3% -20% -40% -40% -52% -
+54% -55%
BUK 57031/s 3% -- -18% -38% -38% -51% -
+52% -53%
sneekyGF 69161/s 25% 21% -- -25% -25% -40% -
+42% -43%
orig 92056/s 67% 61% 33% -- -0% -21% -
+23% -25%
GF 92056/s 67% 61% 33% 0% -- -21% -
+23% -25%
roy 115883/s 110% 103% 68% 26% 26% --
+-3% -5%
VS 119184/s 116% 109% 72% 29% 29% 3%
+ -- -2%
davido 122008/s 121% 114% 76% 33% 33% 5%
+ 2% --
Being sneeky doesn't pay :)
Update for BrowserUK version
DWIM is Perl's answer to Gödel
| [reply] [d/l] [select] |
Re: Simplifying for loop and applying multiple push function
by serf (Chaplain) on Dec 14, 2005 at 21:01 UTC
|
use strict;
use warnings;
my %hash = (
1 => 'one',
2 => 'two',
3 => 'three'
);
my(@one,@two);
while ( my ( $key, $val ) = each %hash ) {
push @one, $val; push @two, $key;
}
| [reply] [d/l] |
Re: Simplifying for loop and applying multiple push function
by qq (Hermit) on Dec 14, 2005 at 22:09 UTC
|
my %hash = ( 1 => 'one' , 2 => 'two' , 3 => 'three' );
no strict;
map { push @{ ++$i % 2 ? 'one' : 'two'}, $_ } %hash;
print "@one\n";
print "@two\n";
Another one-line attempt. But maybe it should count as two... | [reply] [d/l] |
Re: Simplifying for loop and applying multiple push function
by NetWallah (Canon) on Dec 15, 2005 at 04:59 UTC
|
I would question choice of the data structure used.
Given just the context in the OP's question, I would structure %hash as an array, and the problem practically solves itself.
my @arr = qw(one two three);
my @one=@arr;
my @two = 1..$#one+1;
This, ofcourse, assumes the indices (or keys) are sequential, numeric. If this is NOT the case, it is still more convenient to look at the %hash as an array of tuples, and code it as an AOA, since there seems to be an implied requirement to retrieve elements in a particular order.
You're just jealous cause the voices are only talking to me.
No trees were killed in the sending of this message. However, a large number of electrons were terribly inconvenienced.
| [reply] [d/l] |