Re: A better (ie.more concise) way to write this?
by hdb (Monsignor) on Dec 13, 2013 at 15:53 UTC
|
( $a[$_] += 1 ) %= 10 for 0..9;
| [reply] [Watch: Dir/Any] [d/l] |
|
maybe better readable with a custom function in case of deeply nested HoHoH...
DB<132> sub cycle { $_[1]++; $_[1] %= $_[0] }
DB<133> cycle 3 => $h{a}{b}[2]{c}; \%h
=> { a => { b => [undef, undef, { c => 1 }] } }
DB<134> cycle 3 => $h{a}{b}[2]{c}; \%h
=> { a => { b => [undef, undef, { c => 2 }] } }
DB<135> cycle 3 => $h{a}{b}[2]{c}; \%h
=> { a => { b => [undef, undef, { c => 0 }] } }
unfortunately does Perl have no autoboxing, to allow:
$h{a}{b}[2]{c}->cycle(3)
edit
Ha, it can be emulated with ano-subs! =)
DB<160> $cycle = sub { $_[0]++; $_[0] %= $_[1] }
=> sub { "???" }
DB<161> $h{a}{b}[2]{c}->$cycle(3); \%h
=> { a => { b => [undef, undef, { c => 1 }] } }
DB<162> $h{a}{b}[2]{c}->$cycle(3); \%h
=> { a => { b => [undef, undef, { c => 2 }] } }
DB<163> $h{a}{b}[2]{c}->$cycle(3); \%h
=> { a => { b => [undef, undef, { c => 0 }] } }
Cheers Rolf
( addicted to the Perl Programming Language)
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: A better (ie.more concise) way to write this?
by roboticus (Chancellor) on Dec 13, 2013 at 17:13 UTC
|
@a = map { ++$_ % 10 } @a;
If I'm missing the point and you're explicitly wanting to only alter a subset of the items, a slice'll adapt it:
@a = map {++$_ % 10 } @a[0-5,7];
Update: If the point is to modify it in place, I like the AM post above...
...roboticus
When your only tool is a hammer, all problems look like your thumb. | [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
$things{ $thing }{$someotherkey}[$someindex]{$somekey}[ $_ ] = $things
+{ $thing }{$someotherkey}[$someindex]{$somekey}[ $_ ] + 1 % 10 for 1
+.. 10;
You get: @{ $things{ $thing }{$someotherkey}[$someindex]{$somekey} }[ 1 .. 10 ]
+ = map{ ++$_ % 10 } @{ $things{ $thing }{$someotherkey}[$someindex]{$
+somekey} }[ 1 .. 10 ];
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
Then , if you want to modify an existing data structure, what about using the fact that modifying $_ will modify the original array? Something like this, shown under the debugger:
DB<1> @a = 1..9;
DB<2> map{ $_ = ++$_% 10 } @a;
DB<3> x @a
0 2
1 3
2 4
3 5
4 6
5 7
6 8
7 9
8 0
DB<4>
Well, this obviously works, but something like $c = ++$c is, I believe, not defined in C and probably also not in Perl (i.e. the implementor if free to do whatever). It could be changed to:
map { $_ ++; $_ = $_ % 10} @a;
This would probably be more secure against any change of implementation.
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: A better (ie.more concise) way to write this?
by Anonymous Monk on Dec 13, 2013 at 16:38 UTC
|
| [reply] [Watch: Dir/Any] [d/l] |
Re: A better (ie.more concise) way to write this?
by johngg (Canon) on Dec 14, 2013 at 12:47 UTC
|
$ perl -Mstrict -Mwarnings -E '
my @a = ( 1 .. 10 );
sub transform (&@);
@a = transform { ( ++ $_ ) % 10 } @a;
say qq{@a};
sub transform (&@) { map $_[ 0 ]->( $_ ), @_[ 1 .. $#_ ] }'
2 3 4 5 6 7 8 9 0 1
$
Update: Much more concise if you make the transform subroutine operate on $_ by default.
$ perl -Mstrict -Mwarnings -E '
my @a = ( 1 .. 10 );
sub transform (&);
transform { ( ++ $_ ) % 10 } for @a;
say qq{@a};
sub transform (&) { $_[ 0 ]->( $_ ) }'
2 3 4 5 6 7 8 9 10 11
$
Update 2: Just noticed that isn't working properly so will have to investigate why :-(
Update 3: Got it!
$ perl -Mstrict -Mwarnings -E '
my @a = ( 1 .. 10 );
sub transform (&);
transform { $_ = ( ++ $_ ) % 10 } for @a;
say qq{@a};
sub transform (&) { $_[ 0 ]->( $_ ) }'
2 3 4 5 6 7 8 9 0 1
$
| [reply] [Watch: Dir/Any] [d/l] [select] |
Re: A better (ie.more concise) way to write this?
by wind (Priest) on Dec 14, 2013 at 00:56 UTC
|
@a = (1..10);
$_++, $_%=10 for @a;
| [reply] [Watch: Dir/Any] [d/l] |
Re: A better (ie.more concise) way to write this?
by wazat (Monk) on Dec 14, 2013 at 05:00 UTC
|
++$_ < 10 || ( $_ -= 10 ) for @a;
but I see that your original array has 10 as an element | [reply] [Watch: Dir/Any] [d/l] |
Re: A better (ie.more concise) way to write this?
by sundialsvc4 (Abbot) on Dec 17, 2013 at 00:31 UTC
|
Now the dust has settled on this one, I have a question ... yes, a question ...
My solution to this problem came up more-or-less like this:
perl -e 'use strict; use warnings;
my @a = ( 1..10 );
foreach (@a) { $_ = ( $_ + 1 ) % 10; };
use Data::Dumper; print Data::Dumper->Dump([\@a], ["a"]);'
$a = [
2,
3,
4,
5,
6,
7,
8,
9,
0,
1
];
In other words, using the foreach() construct to iterate through the list/array, with $_ being an automatic alias to each entry in succession, rather than actually indexing into the array. Intuitively, this seems to me that this would be “more efficient.” Is it?
Also... among the various solutions that were proffered in this thread, how much difference in timing are we actually talking about here?
| [reply] [Watch: Dir/Any] [d/l] |