Как сгладить хэш пар ключ-значение? - PullRequest
0 голосов
/ 14 января 2012

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

  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 ... не обращайте на них внимания!

Ответы [ 4 ]

6 голосов
/ 14 января 2012

Одним удобным способом является использование URI query_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 , map и join.

3 голосов
/ 15 января 2012

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

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

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

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

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

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

3 голосов
/ 14 января 2012

без модулей:

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 голосов
/ 14 января 2012
use URI::Escape;
my $str=join '&',map {uri_escape($_).'='.uri_escape($QUERY_STRING->{$_})} grep {defined $QUERY_STRING->{$_}} keys %$QUERY_STRING;

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...