Есть ли менее неуклюжая альтернатива для копирования элементов "n"?
В мире многих @choices
С помощью $limit
, что можно сделать,
Жизнь предлагает много @options
Но время от времени один или два.
Чтобы минимизировать линейный шум
Что может Тим Тоуди сделать?
Вот несколько способов, о которых я думал, но они кажутся такими неуклюжими. Конечно, там есть более элегантный способ DWIM:
-
Подробный однострочный
my @choices = @options <= $limit ? @options : @options[0..$limit-1]; # Blech
-
Управление срезами
my @choices = @options[0..(@options <= $limit ? $#options : $limit - 1)]; # Even worse
-
Сырный ломтик внутри среза
my @choices = @options[0..($#options, $limit-1 )[@options > $limit]]; # Crazy eyes
-
Более четкое намерение, но более двух строк
my @choices = @options;
@choices = @options[0..$limit-1] if $limit < @options;
Ответы
Ответ 1
@choices = @options; splice @choices, $limit; # "splice() offset past end" before v5.16
Это также можно сделать в одном выражении!
@choices = splice @{[@options]}, 0, $limit;
А также
splice @{$choices_ref=[@options]}, $limit; # Warns "splice() offset past end" before v5.16
splice $choices_ref=[@options], $limit; # Ditto. Requires Perl v5.14. "Experimental"
Ответ 2
my @choices = @options[0..min($#options, $limit-1)];
Короткий, простой, понятный.
Ответ 3
Из предоставленных вами опций мне действительно нравятся # 1 и # 4, и у них есть определенные письменные заявления, подобные тем, которые были раньше. Если бы эти параметры меня действительно беспокоили, я мог бы написать так:
use strict;
use warnings;
use List::Util qw(min);
use Data::Dumper;
my @options = ('a'..'c');
my $limit = 5;
my @choices = @options[0..min($limit-1, $#options)];
print Dumper \@choices;
# $VAR1 = [
# 'a',
# 'b',
# 'c'
# ];
$limit = 2;
@choices = @options[0..min($limit-1, $#options)];
print Dumper \@choices;
# $VAR1 = [
# 'a',
# 'b'
# ];
но это во многом основано на мнениях, и я уверен, что другие люди сделают это по-другому.
Ответ 4
Я бы использовал splice
:
my @choices = splice ( @options, 0, $limit );
Обратите внимание, что splice
действует как shift
/pop
и изменяет исходный массив - если это нежелательно, то сначала скопируйте его.
Ответ 5
my @choices = first_x_ele($limit, @options);
Если вы думаете, что что-то неясно, используйте суб! Как вы реализуете sub, это не очень важно, но короткий:
sub first_x_ele { my $x = shift; splice(@_, 0, $x) }