按值比较两个哈希以获得 keys/values 其中第二个更大

Compare two hashes by value to get keys/values where the 2nd is greater

我有代码:

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

#Coder: pavel69

open FILE1, "/home/stackovershroom/0/28.12.txt" or die;
my %dec28;
while (my $line1=<FILE1>) {
 chomp($line1);
 (my $plu28, my $count28) = split / /, $line1;
 $dec28{$plu28} = $count28;
}

open FILE2, "/home/stackovershroom/0/29.12.txt" or die;
my %dec29;
while (my $line2=<FILE2>) {
 chomp($line2);
 (my $plu29, my $count29) = split / /, $line2;
 $dec29{$plu29} = $count29;
}

print Dumper \%dec28;
print Dumper \%dec29;

输出:

     $VAR1 = {
     '3203100' => '7',
     '3467390' => '14',
     '3017931' => '19',
     '3312878' => '1.806',
     '3362576' => '56',
     '3173204' => '23',
     '3335495' => '6.377',
     '202' => '30.848',
     '2161067' => '13',
     '3356411' => '6',
     '3483437' => '6',
     '3359188' => '11',
     '...' => '...' #yet more 500 strings!
     };
    $VAR1 = {
     '3153446' => '89.480',
     '2062513' => '9',
     '3386209' => '8.379',
     '3195682' => '17.266',
     '3411129' => '18',
     '3154498' => '4.916',
     '2043226' => '12',
     '...' => '...' #yet more 500 strings!
     };

我想比较两个散列以从 %dec28 中搜索键,其值已递增(从 %dec29 开始)。

为清楚起见,在 %dec28 中我有:

'209198' => '2'

在 %dec29 我有:

'209198' => '13'

在比较 %dec28 <=> %dec29 时需要获取 %dec28 的所有(仅)增量值(增量值包含在 %dec29 中)。我只能得到 %dec29

中出现的新 keys/values

最小示例:

%dec28 = (
         '3091212' => '1',
         '2093334' => '74',
         '209' => '5.600',
         '1947754' => '3',
         '3130087' => '6');

%dec29 = (
         '3091212' => '4',
         '2093334' => '60',
         '209' => '13.844',
         '1947754' => '9',
         '3130087' => '6');

需要新建

%increment_values = (
         '3091212' => '4'
         '209' => '13.844'
         '1947754' => '9');

有可能吗?我该怎么做?

如果我没理解错的话,你想要这样的东西:

# For each key in %dec28
for my $k (keys %dec28) {
  # If the same key exists in %dec29
  # And the %dec29 value is greater than the %dec28 value
  if (exists $dec29{$k} and $dec29{$k} > $dec28{$k}) {
    # Print something useful
    print "$k: $dec28{$k} -> $dec29{$k}\n";
  }
}

我不明白你想做什么,但有一些方法可以比较两个哈希中的平行键。

遍历一个散列的所有键并检查这些键是否在另一个散列中:

foreach my $key1 ( keys %hash1 ) {
    next unless exists $hash2{$key1};
    ... Do whatever you need to do
    }

如果您想要更大的值,您可以将这些值分配给单独的散列:

my %larger;
foreach my $key ( keys %hash1 ) {
    next unless exists $hash2{$key};
    next unless $hash2{$key} > $hash2{$key};
    $larger{$key} = $hash2{$key};
    }

或者,您可以不做任何操作来获取公共密钥:

my @common_keys = grep { exists $hash2{$_} } keys %hash1;

您可以扩展 grep 以更具体:

my @larger_keys = grep { 
    exists $hash2{$_} && $hash2{$_} > $hash1{$_}
    } keys %hash1;

一旦你有了有趣的键,你就可以很容易地得到一个更小的哈希对:

my %larger = 
    map { $_ => $hash2{$_) }
    grep { ... }
    keys %hash1;

对于 v5.20 或更高版本,您可以使用 key-value slices(重复使用我们之前提取的密钥):

use v5.20;
my %larger = %hash2{ @larger_keys };

循环遍历新的散列键 (dec29)。如果密钥存在于旧哈希 (dec28) 中,则比较 2 个值。如果新值更大,将其添加到 increment 散列。

use warnings;
use strict;
use Data::Dumper;
$Data::Dumper::Sortkeys=1;

my %dec28 = (
         '3091212' => '1',
         '2093334' => '74',
         '209' => '5.600',
         '1947754' => '3',
         '3130087' => '6');

my %dec29 = (
         '3091212' => '4',
         '2093334' => '60',
         '209' => '13.844',
         '1947754' => '9',
         '3130087' => '6');

my %increment_values;
for my $k (keys %dec29) {
    if (exists $dec28{$k}) {
        if ($dec29{$k} > $dec28{$k}) {
            $increment_values{$k} = $dec29{$k};
        }
    }
}

print Dumper(\%increment_values);

这是一个紧凑的解决方案,可以是一行。

%day1 = ('3091212' => '1',
         '2093334' => '74',
         '209' => '5.600',
         '1947754' => '3',
         '3130087' => '6');

%day2 = ('3091212' => '4',
         '2093334' => '60',
         '209' => '13.844',
         '1947754' => '9',
         '3130087' => '6');

%incremented_values = 
  map { exists $day1{$_} && $day2{$_} > $day1{$_} ?
    ($_, $day2{$_}) : ()
  } keys %day2;

现在您将键值显示为字符串。如果您需要将它们保留为纯字符串而不对它们进行数值化,则需要复制这些值。


%incremented_values = 
  map { exists $day1{$_} && (my $v2=$day2{$_}) > (my $v1=$day1{$_}) ?
    ($_, $day2{$_}) : ()
  } keys %day2;

HTH