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

Simple enough; I need to repeat a date from an array of dates x number of times and list it to a text file, repeat the next date and list them under the first date, etc. So:
2014-01-01
2014-01-01
2014-01-01
2014-02-02
2014-02-02
2014-02-02
...repeat for more. Le Code:

#!/usr/bin/perl -w use Term::ANSIColor; use Date::Calc qw(Add_Delta_Days); use strict; use warnings; my $START_DATE = &prompt("Please enter the start date (format yyyy-mm- +dd):"); my $END_DATE = &prompt("Please enter the ending date (format yyyy-mm-d +d):"); open LABFILE, '>', "labels.txt"; print LABFILE join("\n", date_list($START_DATE, $END_DATE)); close LABFILE; sub date_list { my ($from, $to) = @_; my @dates = $from; my $intermediate = $from; while ($intermediate ne $to) { $intermediate = sprintf "%04d-%02d-%02d", Add +_Delta_Days(split(/-/, $intermediate), 1); push @dates, $intermediate; } my $first = shift(@dates); my $last = pop(@dates); my $dates = join("\n", @dates); my @multiple = $dates; my @mults = map { "$dates" } @multiple; foreach my $date(@mults) { #return $date; return (($date) x 10); } } sub prompt { my($prompt, $default) = @_; my $defaultValue = $default ? "[$default]" : ""; print color("yellow"), "$prompt $defaultValue", color ("reset"); chomp(my $input = <STDIN>); return $input ? $input : $default; }

...which if you use dates 2014-01-01 to start and 2014-01-10 to end, returning $date (commented out) by itself gives you:
2014-01-02
2014-01-03
..
2014-01-09
..and if you run the uncommented line I get:
02
..through..
09
repeated 10 times. I don't want to repeat the whole array, just repeat each element 10 times in succession. I am prostrate before your light, an empty vessel, yet wide open.

Replies are listed 'Best First'.
Re: Generate list with array elements repeated x times
by toolic (Bishop) on Oct 16, 2014 at 18:23 UTC
    Use this simplified sub (stealing choroba's map):
    sub date_list { my ( $from, $to ) = @_; my @dates = $from; my $intermediate = $from; while ( $intermediate ne $to ) { $intermediate = sprintf "%04d-%02d-%02d", Add_Delta_Days( spli +t( /-/, $intermediate ), 1 ); push @dates, $intermediate; } my $first = shift(@dates); my $last = pop(@dates); return map { ($_) x 10 } @dates; }

    Outputs for me using 2014-01-02 and 2014-01-06:

    2014-01-03 2014-01-03 2014-01-03 2014-01-03 2014-01-03 2014-01-03 2014-01-03 2014-01-03 2014-01-03 2014-01-03 2014-01-04 2014-01-04 2014-01-04 2014-01-04 2014-01-04 2014-01-04 2014-01-04 2014-01-04 2014-01-04 2014-01-04 2014-01-05 2014-01-05 2014-01-05 2014-01-05 2014-01-05 2014-01-05 2014-01-05 2014-01-05 2014-01-05 2014-01-05

      Even simpler. I took out what was below my $last and used the same return line from my response to choroba with @dates instead of @mults. Works perfectly. Thanks toolic.

        You're welcome. I was wondering if there was a way to get rid of your pop/shift, and it turns out you could use splice instead. You determine if this is too clever or not:
        return map { ($_) x 10 } splice @dates, 1, -1;
Re: Generate list with array elements repeated x times
by choroba (Cardinal) on Oct 16, 2014 at 18:12 UTC
    Calling return ends the foreach loop. Replace the loop with the marked line (and try the whole script to test):
    #!/usr/bin/perl use warnings; use strict; use feature qw{ say }; sub date_list { my @mults =qw( 2010-01-01 2010-01-02 2010-01-03 ); return map { ($_) x 10 } @mults; # <--- HERE } say for date_list('2014-01-01', '2014-01-10');
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ

      Excellent. Your code did just what I needed to get the desired output. But as my code makes a list of dates depending on variable start and end dates, I needed to use


      my @mults = split(' ', $dates); return (("$first") x 10), (map { ($_) x 10 } @mults), (("$last") x 10) +;

      ....to get each of the elements listed in the desired form. Just searching on, "use variables with qw()" pointed me to split. I knew it was simple. Now I can see the next tree behind this one in the forest. Thanks choroba.

        No problem. You can simplify it to
        return map { ($_) x 10 } $first, @mults, $last
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ