2013-12-05 3 views
1

В исследовании этого вопроса я заглянул в главу Iterators в книге «Более высокий порядок Perl», а некоторые из материалов были немного над моей головой и не думали, что обязательно будут обращать внимание на то, что я специально хочу здесь ,Создание ленивого хэшированного итератора

Что я имею в виду ленивого хэшированном итератор способ создать структуру, которая будет эмулировать такое поведение:

%Ds = { 
     '1' => 1 .. 20; 
     '2' => 21 .. 40; 
     '3' => 41 .. 60; 
     '4' => 61 .. 80; 
     ... 
    } 

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

Поведение заключается в следующем:

I have a number. 
I need to compare it with a sequence of ranges and as a result of the comparison the 
code/sub would return another number that is the "key" of that range in case the 
number is in that range. (>= with the beginning or <= with the end point of said range) 
The "key" of the ranges are numbers from 1..2..3 and so on. 
The code/sub will always return for a positive integer no matter how large it is. 

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

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

Есть ли способ сделать это с помощью perl-конструкций или, возможно, есть модуль CPAN, который предлагает такое поведение, и мой простой поиск не выявил его.

Вот фрагмент кода, который иллюстрирует то, что я имею в виду:

sub get_nr { 
    my $nr = shift; 
    my %ds = map { $a = '1' if /1/ .. /20/; 
        $a = '2' if /21/ .. /40/; 
        $a = '3' if /41/ .. /60/; 
        $a = '4' if /61/ .. /80/; 
        $_ => $a } 1 .. 80; 

    while (my ($k, $v) = each %ds) { 
    if ($k == $nr){ 
    print "number is in range $v \n"; 
    } 
    } 
} 

Выход для:

get_nr(4); 
get_nr(15); 
get_nr(22); 
get_nr(45); 

ли:

number is in range 1 
number is in range 1 
number is in range 2 
number is in range 3 
+3

Мне сложно понять ваш вопрос, потому что вы продолжаете думать о желании поведения, но вы не описываете никаких поведений. (Кажется, вы описали структуру данных.) Правильно ли вам сказать, что вы хотите функцию, называемую '$ h {$ x}', которая возвращает '$ x * 20-19 .. $ x * 20'? – ikegami

+0

'Ds' - это не Perl-переменная, это гобе. Вы имели в виду '$ Ds'? – TLP

+6

Кроме того, это типичный вопрос, который звучит как XY-проблема: задавать вопрос о решении вместо проблемы, которую вы пытаетесь решить. Было бы полезно узнать, какую проблему вы пытаетесь решить, используя эту технику. – TLP

ответ

2

На основе обсуждения в комментариях код, который вам кажется, нужен av Эри простой подпрограммы

sub get_nr { 
    my $nr = shift; 
    my $range = int(($nr-1)/20) + 1; 
    return $range; 
} 

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

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

+0

Пожалуйста, также добавьте комментарии, что я искал проблему неправильно, не нуждался ни в каких функциональных функциях и т. Д. Также измените имя субстрата на get_range. – user3046061

+0

диапазон должен быть жестко запрограммирован, пример, который я дал в ОП, предложил это. – user3046061

+0

@ user3046061 Вы, кажется, немного закодированы сами, в своем образе мышления. :-) Если это решает ваш вопрос, вы должны подумать о принятии ответа. – TLP

1
sub get_range_number { 
    my ($n) = @_; 
    return int(($n-1)/20) + 1; 
} 

print "$_ is in range ".get_range_number($_)."\n" 
    for 4, 15, 22, 45; 
+1

PS - Обратите внимание, как печать выполняется вне функции. Притяжение не имеет никакого отношения к определению номеров диапазонов. – ikegami

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