如何展平键值对的哈希值?

发布于 2024-12-26 16:48:57 字数 1198 浏览 1 评论 0原文

我想与大家分享我创建的一个函数,看看如何优化它,或者是否有更好的方法来做到这一点。

  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 ...

UPDATED

没有模块的解决方案是首选我真的只是想知道如何有效压平哈希!

请注意,这里的一些函数只是简单的包装函数,它们按照它们的说明执行操作。 isHash getKeys...不用注意那些!

I wanted to share with you guys a function I had created to see how I could optimize it, or if there was a better way to do this.

  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;
  }

Are there any optimization points I should be aware of here?

Basically I want to go from

$HASH => {

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

}

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

UPDATED

a solution without Modules is preferred I really just want to know how to effectively flatten a hash!.

Note that some of the functions here are simply wrapper functions that do what they say. isHash getKeys... pay no attention to those!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

与君绝 2025-01-02 16:49:01
use URI::Escape;
my $str=join '&',map {uri_escape($_).'='.uri_escape($QUERY_STRING->{$_})} grep {defined $QUERY_STRING->{$_}} keys %$QUERY_STRING;

我认为这应该有效!

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

I think this should work!

浅沫记忆 2025-01-02 16:49:00

我在您的问题中看不到任何内容,这意味着您的子例程需要比以下内容更复杂:

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

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

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

更新:在这里获得一些反对票。我假设人们会反对我没有对任何内容进行 URI 编码这一事实。我只是指出,原始问题中没有任何内容表明我们正在构建 URI。如果我知道我们是这样,那么我肯定会使用适当的模块

这就是为什么我说“我在你的问题中看不到任何内容......”。

I can't see anything in your question which means that your subroutine needs to be any more complex than:

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

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

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

Update: Getting a few downvotes here. I assume that people object to the fact that I'm not URI-encoding anything. I'll just point out that there's nothing in the original question saying that we're building URIs. If I knew that we were, then I'd certainly use the appropriate module.

This is why I said "I can't see anything in your question...".

不念旧人 2025-01-02 16:48:59

没有模块:

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

Without modules:

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;

result:

key2=val2&key1=val1&key3=val3
一影成城 2025-01-02 16:48:58

一种方便的方法是使用 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、映射和连接。

One convenient way is to use URI's query_form facility.

use URI;

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

Another, more manual way, is to just use URI::Escape, map, and join.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文