2012-01-13 3 views
-3

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

sub flatten{ 
    my($ref,$delim,$item_delim,$array,$str) = @_; 

    die("Required Hash Reference") unless isHash($ref); 

    $delim = $delim ? $delim :'_'; 

     #dump into array hash vals #simplified 
     if(!$item_delim){ 
     @{$array} = %{$ref}; 
     }else{ 
     my($keys,$values); 

     $keys = getKeys($ref); 
     $values = getValues($ref); 

     #item strings 
     if($#$keys > 0 && $#$values > 0){ 
      #fix for issue where value[n] is empty 
      @{$array}= map{ (defined $$values[ $_ ]) ? $$keys[ $_ ].$item_delim.$$values[ $_ ] : $$keys[ $_ ].$item_delim } 0 .. int($#$keys); 
     }else{ 
     log "No Values to flatten"; 
     return ''; 
     } 
     } 

    $str = join($delim,@{$array}); 
    return $str; 
    } 

Есть ли какие-либо пункты оптимизации, о которых я должен знать здесь?

В основном я хочу, чтобы перейти от

$HASH => { 

key1 => 'val1', 
key2 => 'val2', 
key3 => 'val3', 

} 

в $STRING= key1=val1&key2=val2 ...

Обновлено

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

Обратите внимание, что некоторые из функций здесь - это просто функции-обертки, которые выполняют то, что они говорят. isHash getKeys ... не обращайте на них внимания!

+2

Почему вы используете функцию типа 'isHash',' getKeys', 'getValues'? Является ли эта часть стандартом компании? И не можете ли вы использовать простые массивы и хеши вместо ссылок? – Borodin

ответ

3

Без модулей:

my $hashref = {  
    key1 => 'val1', 
    key2 => 'val2', 
    key3 => 'val3', 
}; 

sub encode { 
    my $str = shift; 
    $str =~ s/([^A-Za-z0-9\.\/\_\-])/sprintf("%%%02X", ord($1))/seg; 
    return $str; 
} 

my $str = join '&' => map { encode($_).'='.encode($hashref->{$_}) } grep { defined $hashref->{$_} } keys %$hashref; 

результат:

key2=val2&key1=val1&key3=val3 
0
use URI::Escape; 
my $str=join '&',map {uri_escape($_).'='.uri_escape($QUERY_STRING->{$_})} grep {defined $QUERY_STRING->{$_}} keys %$QUERY_STRING; 

Я думаю, что это должно сработать!

+0

Не хватает побега. Если ваши ключи или значения содержат любой из [довольно длинный список] (https://metacpan.org/module/URI::Escape) символов, это взорвется. – hobbs

+0

@ hobbs, да, это было !! спасибо! – cirne100

+0

@nodebunny, чтобы сделать это без модулей, используйте регулярное выражение для соответствия всем небезопасным символам и замените его шестнадцатеричным номером, который представляет это! (или очень близко к!) s/([^ [\ w - \. \ ~]])/sprintf ("% 02X", ord $ 1)/eg; – cirne100

6

Одним удобным способом является использование URIquery_form объекта.

use URI; 

my $uri = URI->new("", "http"); # We don't actually care about the path... 
$uri->query_form(%params); 
my $query_string = $uri->query; 

Другой, более ручной способ, чтобы просто использовать URI::Escape, карта, и присоединиться.

+2

@nodebunny Если вы работаете под странными ограничениями, вы должны упомянуть их в своем вопросе. Если вы не хотите использовать модуль, перейдите по адресу http://search.cpan.org/perldoc?URI и посмотрите на источник и возьмите то, что вам нужно. – TLP

+1

@nodebunny, похоже, вы не знаете, что означает слово «сплющивание». Способ сглаживания хэша в perl - '@kv =% hash'. – hobbs

3

Я ничего не вижу в вашем вопросе, что означает, что ваша подпрограмма должна быть более сложной, чем:

sub flatten { 
    my ($hash, $delim, $item_delim) = @_; 

    $delim //= '&', 
    $item_delim //= '='; 

    return join $delim, map { "$_$item_delim$hash->{$_}" } keys %$hash; 
} 

Обновление: Получение нескольких downvotes здесь. Я предполагаю, что люди возражают против того, что я не кодирую URI. Я просто укажу, что в первоначальном вопросе нет ничего, говоря о том, что мы создаем URI. Если бы я знал, что мы были, то я бы обязательно использовал appropriate module.

Вот почему я сказал: «Я ничего не вижу в вашем вопросе ...».

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