Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

Implementing a cyclic array

by perlpal (Scribe)
on Jun 19, 2009 at 11:33 UTC ( [id://772995]=perlquestion: print w/replies, xml ) Need Help??

perlpal has asked for the wisdom of the Perl Monks concerning the following question:

I am trying to implement logic to devise a cyclic array.
A hypothetical use case is as follows :
array_1 = ("tom","harry","diana","nick","sally","henry")
array_2 = ("play()","eat()","sleep()")
The first element in array_1 calls the first function in array_2 i.e. "tom" calls function "play()".Likewise.
The 4th element in array_1 should backtrack to the first elementof array_2 i.e "nick" calls function "play()".Continue the cycle.
Both arrays can have any number of elements with the condition size of array_1 always > saize of array2.
Imput for the above is appreciated! Thanks in advance!

Replies are listed 'Best First'.
Re: Implementing a cyclic array
by GrandFather (Saint) on Jun 19, 2009 at 11:58 UTC

    You can do that in a bunch of different ways (this is Perl we speak of so of course you can). Simplest would be something like:

    use strict; use warnings; my @names = qw(tom harry diana nick sally henry); my @actions = (\&play, \&eat, \&sleep); for my $index (0 .. $#names) { $actions[$index % @actions]->($names[$index]); } sub play { print "$_[0] plays\n"; } sub eat { print "$_[0] eats\n"; } sub sleep { print "$_[0] sleeps\n"; }

    Prints:

    tom plays harry eats diana sleeps nick plays sally eats henry sleeps

    True laziness is hard work
Re: Implementing a cyclic array
by citromatik (Curate) on Jun 19, 2009 at 12:39 UTC

    Tie::Cycle is a simple module that implements cyclic arrays through a tied reference (to the array):

    use strict; use warnings; use Tie::Cycle; my @names = qw/tom harry diana nick sally henry/; tie my $cycle, 'Tie::Cycle', [ sub{print "$_[0] plays\n"}, sub{print "$_[0] eats\n"}, sub{print "$_[0] sleeps\n"} ]; $cycle && $cycle->($_) for (@names);

    Prints:

    tom plays harry eats diana sleeps nick plays sally eats henry sleeps

    The last line ($cycle && $cycle->($_) for (@names);) seems a bit odd, but $cycle->($_) doesn't trigger the FETCH sub in the tied scalar (anybody knows why?) and a first call to $cycle is needed.

    citromatik

Re: Implementing a cyclic array
by johngg (Canon) on Jun 19, 2009 at 15:17 UTC

    You could construct an iterator.

    use strict; use warnings; my @arr1 = qw{ tom harry diana nick sally henry }; my $iterator = do { my $idx = -1; my @actions = ( sub { print qq{$_[ 0 ] plays\n} }, sub { print qq{$_[ 0 ] eats\n} }, sub { print qq{$_[ 0 ] sleeps\n} }, ); sub { $idx ++; $idx = 0 if $idx > $#actions; &{ $actions[ $idx ] }; }; }; $iterator->( $_ ) for @arr1;

    The output

    tom plays harry eats diana sleeps nick plays sally eats henry sleeps

    I hope this is of interest.

    Cheers,

    JohnGG

    Update: Changed array @methods to @actions to avoid confusion since this is nothing to do with OO.

Re: Implementing a cyclic array
by AnomalousMonk (Archbishop) on Jun 19, 2009 at 14:29 UTC
    Yet another way to do it would be with the List::MoreUtils  each_array or  each_arrayref array iterator generator functions.

    The only 'problem' with these functions is that they return the empty list at the end of an iteration cycle to indicate that the cycle has finished, then start the cycle over again with the first array element(s). Because you seem to want to cycle continuously, you would need logic to detect and 'step over' the end condition.

    If you want to roll your own custom iterator, here's an approach (actually, something like this is probably on CPAN already somewhere, I just haven't looked – also, the excellent and freely downloadable Higher-Order Perl discusses this technique in great detail):

    Output:

    Update: Added link to MJD's HOP.

Re: Implementing a cyclic array
by NetWallah (Canon) on Jun 19, 2009 at 20:52 UTC
    In the spirit of TIMTOWTDI, I offer this OO approach:
    use strict; use warnings; my @array_1 = ("tom","harry","diana","nick","sally","henry"); my @obj = map { new Person (name=>$_) } @array_1; $_->action() for @obj; #------------------------------ BEGIN{ package Person; my $actionIndex=0; my @actions = qw (play eat sleep); my %actsub; sub new{ my ($class, %args )= @_; return bless { ACTION => $actions[$actionIndex++ % scalar @acti +ons], %args, }, $class; } sub action{ my $self = shift; $actsub{ $self->{ACTION} }->($self,@_); } # Initialize class ... for my $actname (@actions){ $actsub{$actname} = sub { my $self = shift; print $self->{name} . " likes to $actname\n"; } } 1; }
    Which produces:
    tom likes to play harry likes to eat diana likes to sleep nick likes to play sally likes to eat henry likes to sleep

         Potentia vobiscum ! (Si hoc legere scis nimium eruditionis habes)

Re: Implementing a cyclic array
by JavaFan (Canon) on Jun 19, 2009 at 11:48 UTC
    Use the % operator.
Re: Implementing a cyclic array
by Anonymous Monk on Jun 19, 2009 at 11:43 UTC
    Show what you tried (perl code).
      the code i've written to map the elements is as follows :
      foreach (@array_1) { print "$array_2[0] maps to $_\n"; push(@array_2, shift @array_2); }
        While many of the other solutions are perhaps a closer fit to your problem, I thought that I would show you a solution that is closer to the code that you tried:
        use strict; use warnings; my @array_1 = ("tom","harry","diana","nick","sally","henry"); my @array_2 = ("play()","eat()","sleep()"); foreach (@array_1) { my $action = shift(@array_2); print "$action maps to $_\n"; push(@array_2, $action); } which prints play() maps to tom eat() maps to harry sleep() maps to diana play() maps to nick eat() maps to sally sleep() maps to henry

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://772995]
Approved by GrandFather
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (2)
As of 2024-04-20 05:01 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found