perl比较哈希中的所有组合

时间:2014-01-15 08:31:47

标签: perl hash combinations

我需要比较哈希元素并挑选出所有不同的对。 为了简化,

my %hash = (
      'row1' => { 'id_a' => 0.5 , 'id_b' => 0.5, 'id_c' => 0.5, 'id_d'=> 0.5 },
      'row2' => { 'id_a' => 0.5 , 'id_b' => 0  , 'id_c' => 0.5, 'id_d'=> 0.5 }
      'row3' => { 'id_a' => 0.5 , 'id_b' => 0.5, 'id_c' => 0  , 'id_d'=> 0   }
      ... 50 more rows of 'rowx'    

);

所需/输出: 输入:%hash 输出:所有值不同的对: row2-id_a / id_b,row2-id_b / id_c,row2-id_b / id_d。 row3-id_a / id_c,row3-id_a / id_d,row3-id_b / id_c,row3-id_b / id_d。

对于所有可能的对,将在一行内进行比较。

while( ($k, $v) = each %hash ) {
   # foreach my $rowkey (sort keys %{$hash{$k}}) {
   #   if ($hash{$rowkey}->{$current key} == $hash{$rowkey}->{$next key} ) {
   #   good to go }
   #   else { do something }
}

此伪代码仅比较相邻元素。我需要比较所有组合。感谢。

3 个答案:

答案 0 :(得分:2)

for my $row ( sort keys %hash ) {
    if ( $hash{$row}{'id_a'} != $hash{$row}{'id_b'} || $hash{$row}{'id_b'} != $hash{$row}{'id_c'} ) {
        print "row $row has different values\n";
    }
}

检查任意数量的值:

use List::MoreUtils 'uniq';
...
    if ( uniq( values %{ $hash{$row} } ) > 1 ) {
        print "row $row has different values\n";
    }

(虽然这会检查唯一的字符串,但检查的数字比检查唯一数字要弱一些。)

答案 1 :(得分:2)

my %hash = (
      'row1' => { 'id_a' => 0.5 , 'id_b' => 0.5, 'id_c' => 0.5 },
      'row2' => { 'id_a' => 0.5 , 'id_b' => 0.0, 'id_c' => 0.5 }
);

for my $k (sort keys %hash) {

  my @rkeys = sort keys %{ $hash{$k} };

  for my $rk (0 .. $#rkeys-1) {
    my ($current, $next) = @rkeys[$rk, $rk+1];

    if ($hash{$k}{$current} != $hash{$k}{$next}) {
      print "difference at : $k-$current/$next\n";
    }
    # else {}
  }
}

输出

difference at : row2-id_a/id_b
difference at : row2-id_b/id_c

答案 2 :(得分:0)

添加到mpapec的答案,

foreach my $layer1 (sort keys %hash){
    print "$layer1: \n";
    my @layer2 = sort keys %{$hash{$layer1}};
    print "@layer2\n";
    #loop pst elements.  All combinations.  Outer loop: increment reference point.  Inner loop: compare values from ref to end of hash row.
    for my $rk (0 .. $#layer2-1) {
            #Get current key.
            my $current = @layer2[$rk];
            #Increment from reference point to the end of the hash row.
            for my $rk_inc ($rk+1 .. $#layer2) {
            #Get hash key for comparison.
            my $next = @layer2[$rk_inc];
                    print "Comparing : " . $current . " ". $next. " \n";
                    if ( ( $hash{$layer1}{$current} != $hash{$layer1}{$next} ) ) { 
                    ## Do something here.
                    }
            }
     }
}