Как я могу обработать вложенное цикличное выполнение без вложения foreach операторы в Perl?

Сохраните время, когда последние пять строк были отправлены. Держите сообщения с очередями до времени пятое новое сообщение (если оно существует), наименьшее количество 8 секунд в прошлом (с last_five как массив времен):

now = time.time()
if len(last_five) == 0 or (now - last_five[-1]) >= 8.0:
    last_five.insert(0, now)
    send_message(msg)
if len(last_five) > 5:
    last_five.pop()
5
задан Eric Leschinski 5 January 2014 в 02:10
поделиться

7 ответов

Я не понимаю, в чем ваша проблема, но вы можете использовать универсальное декартово произведение, если вы привыкли к SQL или чему-то еще:

sub cartesian {
    my @C = map { [ $_ ] } @{ shift @_ };
    foreach (@_) {
        my @A = @$_;
        @C = map { my $n = $_; map { [ $n, @$_ ] } @C } @A;
    }
    return @C;
}

my @sites = ('a', 'b', 'c');
my @servers = ('A', 'B');
my @data_type = ("X", "Y", "Z");

foreach (cartesian(\@sites, \@servers, \@data_type)) {
    ($data, $server_type, $site) = @$_;
    print "$site $server_type $data\n";
}
3
ответ дан 14 December 2019 в 08:56
поделиться

Используйте мой модуль Set :: CrossProduct или используйте Algorithm :: Loops . Для решения этих проблем не нужно создавать жестко запрограммированные вложенные структуры. Оба этих модуля могут сделать это за вас для произвольного количества массивов.

use Set::CrossProduct;

my @sites = ('a', 'b', 'c');
my @servers = ('A', 'B');
my @data_type = ("X", "Y", "Z");

my $cross = Set::CrossProduct->new( 
    [ \@sites, \@servers, \@data_type ]
    );

while( my $tuple = $cross->get ) {
    print "@$tuple\n";
    }

Не только это, но и курсор дает вам возможность перемещаться в итераторе, поэтому вам не нужно ограничивать себя текущей комбинацией. Вы можете проверить предыдущую и следующую комбинации, что может быть полезно для определения границ (например, когда следующий кортеж является другим сервером).

Остерегайтесь людей, которые хотят создать все комбинации в памяти. В этом тоже нет необходимости.

Остерегайтесь людей, которые хотят запоминать все комбинации. В этом тоже нет необходимости.

Остерегайтесь людей, которые хотят запоминать все комбинации. В этом тоже нет необходимости.

6
ответ дан 14 December 2019 в 08:56
поделиться

Вы можете просто использовать для .

(извините, не удержался)

2
ответ дан 14 December 2019 в 08:56
поделиться

foreach предпочтительнее, поскольку он читается. Что именно вы имеете в виду под «каждый массив может вызывать проблемы» (какие проблемы?) И «значения могут не совпадать» (какие значения?)

1
ответ дан 14 December 2019 в 08:56
поделиться

If I understand your question correctly then you asking how to use hashes with foreach to avoid mismatches that you would have in your array example?.

If so then here is one example:

use strict;
use warnings;

my %sites = (

    a => { 
        A => {
            data_type => [ 'X', 'Y' ],
        }
    },

    b => {
        B => {
            data_type => [ 'Y', 'Z' ],
        }
    },

    c => {

    },
);

for my $site ( keys %sites ) {
    for my $server ( keys %{ $sites{ $site } } ) {
        for my $data ( keys %{ $sites{ $site }{ $server } } ) {
            my @data_types = @{ $sites{ $site }{ $server }{ data_type } };
            say "On site $site is server $server with $data @data_types";
        }
    }
}


You can also use while & each which does produces easier code on the eye:

while ( my ( $site, $site_info ) = each %sites ) {
    while ( my ( $server, $server_info ) = each %{ $site_info } ) {
        my @data_types = @{ $server_info->{data_type} };
        say "On site $site we have server $server with data types @data_types"
            if @data_types;
    }
}

Also note I removed last loop in above example because its currently superfluous with my example hash data.

NB. If you plan to amend keys or break out of loop then please read up on each and how it affects the iteration.

PS. This example is not about the loop but about data being best represented as a Hash and not an Array! (though its not clear 100% from question that is so!).

1
ответ дан 14 December 2019 в 08:56
поделиться

Единственное, что меня беспокоит при использовании вложенных циклов, это некоторая двусмысленность в том, что такое $ _ . Учитывая, что вы даже не используете его, я не думаю, что есть лучший способ делать то, что вы хотите.

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

Есть ли у вас какие-либо специфические проблемы с кодом?

-1
ответ дан 14 December 2019 в 08:56
поделиться

Вы можете использовать классический ] вместо цикла .

for(my $i = 0; $i <= $#sites; $i++){
    for(my $j = 0; $j <= $#servers; $j++){
        for(my $k = 0; $k <= $#data_type; $k++){
            do_functions ...

Но это все еще оставляет проблемы и несоответствия, на которые вы ссылались. Я предлагаю вам решить эти проблемы в части do_functions .

-5
ответ дан 14 December 2019 в 08:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: