Zaid Zaid - 3 months ago 8
Perl Question

Is there a less clumsy alternative for copying up to "n" array elements?


In a world of many
@choices


With a
$limit
to what one can do,

Life proposes many
@options


But at times just one or two.

In a bid to minimize line noise

What can Tim Toady do?


Here are a few ways I've thought of, but they just seem so clumsy. Surely there's a more elegant way to DWIM:


  • Verbose one-liner

    my @choices = @options <= $limit ? @options : @options[0..$limit-1]; # Blech

  • Slice control

    my @choices = @options[0..(@options <= $limit ? $#options : $limit - 1)]; # Even worse

  • Cheesy slice inside a slice

    my @choices = @options[0..($#options, $limit-1 )[@options > $limit]]; # Crazy eyes

  • Clearer intent, but over two lines

    my @choices = @options;
    @choices = @options[0..$limit-1] if $limit < @options;


mob mob
Answer
@choices = @options; splice @choices, $limit;  # "splice() offset past end" before v5.16

It can also be done in a single statement!

@choices = splice @{[@options]}, 0, $limit;

And also

splice @{$choices_ref=[@options]}, $limit;  # Warns "splice() offset past end" before v5.16
splice $choices_ref=[@options], $limit;     # Ditto. Requires Perl v5.14. "Experimental"