Как мне сделать простое сравнение эквивалентности хеша Perl? - PullRequest
8 голосов
/ 12 февраля 2009

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

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

ТИА!

Ответы [ 8 ]

13 голосов
/ 12 февраля 2009

Что-то вроде cmp_deeply доступно в Test :: Deep ?

4 голосов
/ 12 февраля 2009

[Это был ответ на ответ того, кто удалил свой ответ.]

Ой!

%a ~~ %b && [sort values %a] ~~ [sort values %b]

не проверяет, принадлежат ли значения одним и тем же ключам.

#! perl
use warnings;
use strict;

my %a = (eat => "banana", say => "whu whu"); # monkey
my %b = (eat => "whu whu", say => "banana"); # gorilla
print "Magilla Gorilla is always right\n" 
    if %a ~~ %b && [sort values %a] ~~ [sort values %b];
1 голос
/ 10 марта 2012

Спасибо за ваш вопрос.

Я использовал Test :: More :: eq_hash в качестве результата.

1 голос
/ 12 февраля 2009

Я не знаю, есть ли простой способ или встроенный пакет, и я не знаю, что происходит, когда вы просто делаете %hash1 == %hash2 (но это, вероятно, не так), но это не очень сложно свернуть ваш собственный:

sub hash_comp (\%\%) {
  my %hash1 = %{ shift };
  my %hash2 = %{ shift };
  foreach (keys %hash1) {
    return 1 unless defined $hash2{$_} and $hash1{$_} == $hash2{$_};
    delete $hash1{$_};
    delete $hash2{$_};
  }
  return 1 if keys $hash2;
  return 0;
}

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

Если вы хотите что-то из стандартного дистрибутива, вы можете use Data::Dumper; и просто сбросить два хэша в две скалярные переменные, а затем сравнить строки на равенство. Это может сработать.

В CPAN есть также пакет под названием FreezeThaw, который выглядит так, как будто он делает то, что вам нужно.

Обратите внимание, что для использования умного совпадения (здесь оно не повторяется, поскольку оно уже опубликовано), вам потребуется use feature;, и оно доступно только для Perl 5.10. Но кто все еще использует Perl 5.8.8, верно?

0 голосов
/ 18 марта 2015

Вы можете использовать eq_deeply в Test :: Deep :: NoTest . Он просто возвращает логическое значение, которое вы можете проверить, без дополнительных затрат на возможности тестирования основного модуля .

0 голосов
/ 27 мая 2011

конвертировать хеши в XML-файлы и сравнивать, и да, вы можете использовать многоуровневый.

sub isEqualHash 
{
    my ($self,$hash1, $hash2) = @_;
    my  $file1 = "c:/neo-file1.txt";
    my  $file2 = "c:/neo-file2.txt";
    my $xmlObj = XML::Simple->new();
    my $dummy_file = $xmlObj->XMLout($hash1,OutputFile => $file1);
    my $dummy_file = $xmlObj->XMLout($hash2,OutputFile => $file2);

    open FILE, "<".$file1;
    my $file_contents1 = do { local $/; <FILE> };
    close(FILE);

    open FILE, "<".$file2;
    my $file_contents2 = do { local $/; <FILE> };
    close(FILE);

    if($file_contents1 eq $file_contents2)
    {
        return "Passed";
    }
    else
    {
        return "Failed";
    }
}
0 голосов
/ 15 июля 2010
Хэши

могут быть преобразованы в массивы, где каждое значение следует за его ключом (но вы не будете знать порядок ключей). Итак:

( join("",sort(%hash1)) eq join("",sort(%hash2)) )

Ой, подождите, это не сработает, потому что есть некоторые крайние случаи, например:

%hash1 = { 'aaa' => 'aa'  };
%hash2 = { 'aa'  => 'aaa' };

Так что лучше всего использовать символ в join (), который, как вы ЗНАЕТЕ, никогда не появится ни в каком ключе или значении. Если значения являются BLOB-объектами, это будет большой проблемой, но для всего остального вы можете использовать NULL-символ "\ 0".

( join("\0",sort(%hash1)) eq join("\0",sort(%hash2)) )

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

0 голосов
/ 13 февраля 2009

Для мелких хешей:

(grep {exists %hash2{$_}} keys %hash1) > 0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...