Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

perl

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;
    
like image 775
Zaid Avatar asked Aug 18 '16 15:08

Zaid


2 Answers

@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"
like image 145
mob Avatar answered Oct 04 '22 19:10

mob


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

Short, straightforward, clear.

like image 35
ikegami Avatar answered Oct 04 '22 19:10

ikegami