2012-03-21 5 views
11

Say подпрограмма Perl возвращает массив:Как я могу выборочно обращаться к элементам, возвращаемым подпрограммой Perl?

sub arrayoutput 
{ 
    ...some code... 
    return @somearray; 
} 

Я хочу получить доступ только конкретный элемент массива из этого, скажем, первых. Так что я мог бы сделать:

@temparray=arrayoutput(argument); 

, а затем обратитесь к $temparray[0].

Но этот вид короткой справки не работает: $arrayoutput(some argument)[0].

Я привык к Python и новый для Perl, поэтому я все еще ищу короткий, интуитивный, похожий на питон способ (a=arrayoutput(some argument)[0]), чтобы получить это значение. Мои программы Perl становятся очень длинными, и использование временных массивов вроде бы кажется уродливым. Есть ли способ в Perl сделать это?

ответ

10

Slices

use warnings; 
use strict; 

sub foo { 
    return 'a' .. 'z' 
} 

my $y = (foo())[3]; 
print "$y\n"; 

__END__ 

d 

UPDATE: Еще один пример кода для решения Вашего комментария. Вам не нужна промежуточная переменная:

use warnings; 
use strict; 

sub foo { 
    return 'a' .. 'z' 
} 

print((foo())[7], "\n"); 

if ((foo())[7] eq 'h') { 
    print "I got an h\n"; 
} 

__END__ 

h 
I got an h 
+0

+1, это работает. Но снова мне нужно создать промежуточную переменную для доступа к значению. Но это на один шаг лучше, так как я могу хотя бы использовать его, когда мне все равно понадобится переменное назначение. Но не в других сценариях, скажем, оператор 'print (foo()) [3]' или оператор 'if ((foo()) [3] ...)'. –

+0

Вы можете делать обе эти вещи. См. Мой обновленный ответ. – toolic

+2

Обратите внимание, что 'print (foo()) [7]' не будет работать должным образом, поскольку perl предполагает, что скобки принадлежат вызову функции, и, таким образом, анализирует его как эквивалент '(print foo()) [7] '. Либо 'print ((foo()) [7])' или, более идиоматически, 'print + (foo()) [7]' будет работать. –

2

Один способ может быть [(arrayoutput(some argument))]->[0].

+0

+1, это работает! Я не понимаю, почему это сокращается. Есть ли какая-то плохая практика программирования или что-то еще происходящее здесь, что мне не хватает? –

+1

Нет необходимости использовать ссылку на массив. Наверное, это и есть причина для понижения. –

14

стянуть первого аргумента только через контекст списка:

my ($wanted) = array_returning_sub(@args); 

TIMTOWTDI с ломтиком:

my $wanted = (array_returning_sub(@args))[0]; 

Оба стиля могли быть расширенным, чтобы извлечь n-й элемент возвращенного массива, хотя фрагмент списка немного проще на глазу:

my (undef, undef, $wanted, undef, $needed) = array_returning_sub(@args); 

my ($wanted, $needed) = (array_returning_sub(@args))[2,4]; 
+0

Читайте как '" возвращающий массив вспомогательный массив '', а не '', возвращающий [a] sub "' – Zaid

+1

Кроме того, subs не могут возвращать массивы. Они могут возвращать только списки скаляров. – ikegami

+0

+1. Так что это был просто вопрос о скобках! Слайд списка также лучше, чем контекст списка для длинных списков. –

Смежные вопросы