LINUX.ORG.RU

Поделитесь мудростью, гуру

 


0

2

Написал, я к примеру, такое:

@larr = qw /a b c d e f/;
@rarr = qw /a b c d/;

@bigger = @larr;
@smaller = @rarr;
if (@rarr > @larr) {
    @bigger = @rarr;
    @smaller = @larr;
}

for (my $i = 0; $i < @bigger; $i++) {
    print "bigger: $bigger[$i], ";
    if (defined $smaller[$i]) {
        print "smaller: $smaller[$i]\n";
    } else {
        print "smaller: 'null'\n";
    }
}
Как это же самое сделать красивее/лаконичнее? Заранее спасибо.

★★

красивее

use strict;
use warnings;

лаконичнее

Код то я вижу, только не пойму, что ты хочешь достичь в конце (Сравнить два массива?). Т.е. скажи еще что тебе надо, тогда и код можно будет подстроить. Так что не буду пока что писать код.

P.S. В Perl цикл for по индексам медленее чем for-each. Т.е. вот такое будет работать быстрее (конечно зависит от размера данных):

my $i = 0;
for my $el (@bigger) {
  # код
} continue {
  ++$i;
}

KennyMinigun ★★★★★
()
Ответ на: комментарий от KennyMinigun

В оригинале strict и warnings в наличии; здесь убрал ради экономии места.

А задача проста - есть два массива, выводить попарно элементы из обоих массивов, заменяя отсутствующие элементы в более коротком какой-то строкой, например, null.

braboar ★★
() автор топика

Напиши по-англицки и создай задачку на jagc.org

anonymous
()
($bigger, $smaller) = @aa > @bb ? \(@aa,@bb) : \(@bb,@aa);
anonymous
()
Ответ на: комментарий от KennyMinigun

Хотя если нет List::MoreUtils, то можно навелосипедить:


my $max_idx = @left > @right ? $#left : $#right;
for my $i (0 .. $max_idx) {
  printf "%s %s\n", $left [$i] // 'null', $right[$i] // 'null';
}

KennyMinigun ★★★★★
()

также можно сделать и просто

 for(@bigger) 
{
  и тут уже делать с $_ 
}

pinachet ★★★★★
()

Присоединяюсь к вечеринке.

my @larr = qw /a b c d e f/;
my @rarr = qw /a b c d/;


my @bigger_array = (@larr > @rarr) ? @larr
                                   : @rarr;
                                         
my @smaller_array = (@larr < @rarr) ? @larr
                                    : @rarr;
                                         
                                        
for (my $i = 0; $bigger_array[$i]; $i++) {
    print "bigger $bigger_array[$i]; smaller: ";
    
    print $smaller_array[$i] ? $smaller_array[$i] 
                             : "null";
    print "\n";
}
Kronick
()

Написал, я к примеру, такое

Закусывать надо.

no-such-file ★★★★★
()
use strict;
use warnings;

my @arr1 = qw/a b c d e/;
my @arr2 = qw/f g h/;

map {
  my $var1 = defined($arr1[$_]) ? $arr1[$_] : 'null';
  my $var2 = defined($arr2[$_]) ? $arr2[$_] : 'null';
  print($var1, ' ', $var2, "\n");
} (0..(@arr1 > @arr2 ? $#arr1 : $#arr2) );
shell-script ★★★★★
()
Ответ на: комментарий от shell-script

Пожалуй, то, что надо. Спасибо. $var1 и $var2, действительно, не нужны. Вполне себе читабельно. Я, в итоге написал такое:

for (my $i = 0; $i < $len; $i++) {
    defined $larr[$i] ? print $larr[$i]." " : print "'null' ";
    defined $rarr[$i] ? print $rarr[$i]."\n" : print "'null'\n";
}
но ваш вариант лучше. Еще раз спасибо.

braboar ★★
() автор топика
Ответ на: комментарий от KennyMinigun

Я слишком много работаю с legacy, поэтому часто на автомате применяю старые конструкции. :)

shell-script ★★★★★
()
use strict;
use warnings;
use feature 'say';

my @larr = qw /a b c d e f/;
my @rarr = qw /a b c d/;

my ($bigger, $smaller) = (@rarr > @larr) ? (\@rarr, \@larr)
                                         : (\@larr, \@rarr);

for my $i (0 .. $#$bigger) {
    say("bigger: $bigger->[$i], ",
        "smaller: ", $smaller->[$i] // "'null'");
}
evbogdanov
()
Ответ на: комментарий от braboar

$bigger, $smaller - это ссылки на массивы.

То есть если (@aa > @bb) то $bigger указывает на адрес массива aa, а $smaller на адрес массива bb

Kronick
()
Ответ на: комментарий от braboar
\(@aa,@bb) разворачивается в (\@aa, \@bb)[\code]
anonymous
()
Ответ на: комментарий от anonymous

Зачем в 2018 году мучить Perl? Дайте уже ему умереть спокойно

  • если вы мучаетесь с перлом, умрите спокойно
  • если вы мучаете перл, перестаньте его мучить
braboar ★★
() автор топика
Последнее исправление: braboar (всего исправлений: 1)
Ответ на: комментарий от evbogdanov

ИМХО:

$#$bigger лучше заменить на $#{$bigger}

Проблема может быть в том, что в любом из этих списков могут оказаться undef, поэтому по-нормальному нужно делать «// 'null'» для всех элементов обоих списков, иначе можно попытаться в качестве $bigger->[$i] вывести undef, а это будет warning, который вполне может оказаться фатальным.

За отсутствием типизации perl местами конечно тот ещё параноидальный геморрой.

DRVTiny ★★★★★
()

Как это же самое сделать красивее/лаконичнее?

Переписать на питоне.

Im_not_a_robot ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.