【问题标题】:How can I quickly filter a hash given an array of keys?如何在给定键数组的情况下快速过滤散列?
【发布时间】:2012-01-12 21:10:47
【问题描述】:

这是一个过度设计的解决方案,我认为可以做得更好。基本上,它需要一个键数组来创建一个过滤器字符串,它会针对散列中的每个键进行检查,以查看该键是否在过滤器字符串中具有索引...排除标志翻转逻辑以包含或排除基于_filter 的结果。可能不是最好的方法。还有更好的方法吗?

  sub _filter{
    my ($filter,$key,$joiner) = @_;
    $joiner = $joiner ? $joiner : '+';
    my $i = index($filter,$key);
    if($i >= 0){  
      my $c;
      $c = substr($filter, $i-1, 1); 

      print STDERR "\nc => $c [$key][$i]";

      if($i==0){ return 1; }
      return($c eq $joiner);  
    }
    return 0;
  }

  sub hashFilter{
    my($hash,$filter_keys,$exclude) = @_;
    return 0 unless isHash($hash) && $filter_keys;

    $exclude = $exclude ? $exclude : 0;
    my $filter = isArray($filter_keys)? join('+',@$filter_keys) : $filter_keys;
    print STDERR "FILTER is > $filter";

    my $p = {map { ( _filter($filter,$_) == $exclude )  ? ($_ => $$hash{$_}) : () } keys %$hash};

    return $p;
  }

#isArray() and isHash() just check the ref value for "ARRAY" or "HASH" respectively

...使用标准 perl 而无需额外的模块! =]

这里有一些想法?

使用地图和索引...这些快速方法与使用正则表达式相比,还是有更好的功能可以使用?

【问题讨论】:

    标签: arrays perl hash filter


    【解决方案1】:
    我的 %filtered_hash = map { $_ => $hash{$_} } grep { 存在 $hash{$_} } @filter_keys;

    【讨论】:

    • 或者把map和grep打包在一起map {exists $hash{$_} ? ($_ => $hash{$_}) : ()} @filter_keys
    • @EricStrom 这正是我想要的!简短而甜蜜。
    【解决方案2】:

    哈希切片,有人吗? :

    my %filtered_hash;
    @filtered_keys = grep { exists $hash{$_} } @filtered_keys;
    @filtered_hash{@filtered_keys} = @hash{@filtered_keys};
    

    【讨论】:

    • 这会将undefs 添加到原始哈希中不存在的键的过滤哈希中,但您可以通过使用@filtered_keys = grep exists $hash{$_}, @filtered_keys; 预处理键列表来解决此问题。
    猜你喜欢
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-24
    • 2018-10-21
    • 2015-10-27
    • 1970-01-01
    相关资源
    最近更新 更多