Come faccio a confrontare due hash in Perl senza usare Data :: Compare?Come faccio a confrontare due hash in Perl senza usare Data :: Compare?
risposta
L'approccio migliore differisce in base ai propri scopi. L'elemento FAQ menzionato da Sinan è una buona risorsa: How do I test whether two arrays or hashes are equal?. Durante lo sviluppo e il debug (e ovviamente durante la scrittura dei test unitari) ho trovato che Test::More
è utile quando si confrontano matrici, hash e strutture dati complesse. Un semplice esempio:
use strict;
use warnings;
my %some_data = (
a => [1, 2, 'x'],
b => { foo => 'bar', biz => 'buz' },
j => '867-5309',
);
my %other_data = (
a => [1, 2, 'x'],
b => { foo => 'bar', biz => 'buz' },
j => '867-5309x',
);
use Test::More tests => 1;
is_deeply(\%other_data, \%some_data, 'data structures should be the same');
uscita:
1..1
not ok 1 - data structures should be the same
# Failed test 'data structures should be the same'
# at _x.pl line 19.
# Structures begin differing at:
# $got->{j} = '867-5309x'
# $expected->{j} = '867-5309'
# Looks like you failed 1 test of 1.
Sembra che Test :: Deep sia stato ispirato da is_deeply. La mia domanda è: come faccio a rendere cmp_deeply parte di un test invece di un test da solo? Perché la mia lista di test dice solo 8, ma ogni volta che uso cmp_deeply, conta come un test, rendendo il mio numero effettivo di test 11 (perché chiamo cmp_deeply 3 volte) quando ho solo 8 funzioni. Non voglio aumentare il numero dei miei test. C'è una soluzione più praticabile? – biznez
@yskhoo. Ogni volta che chiami una delle funzioni di test ('ok',' cmp_deeply', ecc.) Conta come un test. Per quanto ne so, non c'è un modo per evitarlo. Se non si desidera eseguire il commit in anticipo su un numero specifico di test, è possibile farlo quando si carica il modulo di test: 'use Test :: More qw (no_plan);'. – FMc
L'hai già chiesto in http://stackoverflow.com/questions/1274756/how-can-i-use-perls-testdeepcmpdeeply-without-increasing-the-test-count. Non hai risposto perché non è possibile aumentare il numero di test o la complessità della struttura dei dati che è necessario chiamare per tre volte cmp_deeply. Per favore, fai un passo indietro dalle domande che stai ponendo e determina quale sia il vero problema. Se vuoi fornire ulteriori informazioni, forse possiamo aiutarti. – Ether
Vedi How do I test whether two arrays or hashes are equal?
FAQ di Perl e le risposte sono parte di te la distribuzione Perl. È possibile visualizzare la versione di questa risposta fornita con il perl
eseguendo:
$ perldoc -q equal
nel terminale.
Qual è la differenza tra cmpStr e cmpStrHard in FreezeThaw? – biznez
Confronta non è una frase abbastanza dettagliate quando si parla di hash. Esistono molti modi per confrontare gli hash:
Hanno lo stesso numero di chiavi?
if (%a == %b) {
print "they have the same number of keys\n";
} else {
print "they don't have the same number of keys\n";
}
Le chiavi sono le stesse in entrambi gli hash?
if (%a != %b) {
print "they don't have the same number of keys\n";
} else {
my %cmp = map { $_ => 1 } keys %a;
for my $key (keys %b) {
last unless exists $cmp{$key};
delete $cmp{$key};
}
if (%cmp) {
print "they don't have the same keys\n";
} else {
print "they have the same keys\n";
}
}
Hanno le stesse chiavi e gli stessi valori in entrambi gli hash?
if (%a != %b) {
print "they don't have the same number of keys\n";
} else {
my %cmp = map { $_ => 1 } keys %a;
for my $key (keys %b) {
last unless exists $cmp{$key};
last unless $a{$key} eq $b{$key};
delete $cmp{$key};
}
if (%cmp) {
print "they don't have the same keys or values\n";
} else {
print "they have the same keys or values\n";
}
}
Sono essi isomorfe (io lasciare questo uno fino al lettore come non ho particolarmente voglia di provare l'attuazione da zero)?
O qualche altra misura di uguale?
E, ovviamente, questo codice riguarda solo gli hash semplici. L'aggiunta di strutture dati complesse lo rende ancora più complesso.
rapida, sporco, e sono sicuro che non efficiente:
use strict;
use warnings;
use Data::Dumper;
sub compare ($$) {
local $Data::Dumper::Terse = 1;
local $Data::Dumper::Indent = 0;
Dumper(shift) eq Dumper(shift);
}
my %a = (foo => 'bar', bar => [ 0 .. 3 ]);
my %b = (foo => 'bar', bar => [ 0 .. 3 ]);
my %c = (foo => 'bar', bar => [ 0 .. 4 ]);
print Dumper compare \%a, \%b;
print Dumper compare \%a, \%c;
Questo approccio più ['Testo :: Diff'] (https://metacpan.org/module/Text::iff) stampa un rapporto utile. – Lumi
Inoltre dovresti fare 'local $ Data :: Dumper :: Sortkeys = 1;' per garantire lo stesso ordine delle chiavi. – skaurus
@skaurus: perché? Non sarebbero nello stesso ordine? – zakovyrya
per il confronto:
sub HashCompare {
my ($a, $b) = @_;
my %rhash_1 = %$a;
my %rhash_2 = %$b;
my $key = undef;
my $hash_2_line = undef;
my $hash_1_line = undef;
foreach $key (keys(%rhash_2)) {
if (exists($rhash_1{$key})) {
if ($rhash_1{$key} ne $rhash_2{$key}) {
print "key $key in $file_1 = $rhash_1{$key} & $rhash_2{$key} in $file_2\n";
}
}
}
else {
print "key $key in $file_1 is not present in $file_2\n";
#next;
}
}
foreach my $comp_key (keys %rhash_1) {
if (!exists($rhash_2{$comp_key})) {
print MYFILE "key $comp_key in $file_2 is not present in $file_1\n";
}
}
return;
}
Creazione di hash senza chiavi duplicate:
sub CreateHash {
my (@key_val_file) = @_;
my $key_count = 1;
my %hash_key_val =();
my $str4 = undef;
local $/ = undef;
foreach my $each_line (@key_val_file) {
@key_val = split(/,/, $each_line);
if (exists($hash_key_val{$key_val[0]})) {
$key_count = $key_count + 1;
$str4 = $key_val[0] . " occurence-" . $key_count;
$hash_key_val{$str4} = $key_val[1];
}
else {
$hash_key_val{$key_name} = $key_val[1];
}
}
}
$key_count = 1;
close FILE;
return %hash_key_val;
}
si prega di fornire una spiegazione per la risposta. –
da dove proviene $ key_name? – nurp
@zakovyrya Vedere questa risposta: https://stackoverflow.com/a/2011443/2606517 L'ordine delle chiavi proviene da una base dati interna.
Test::Deep::NoTest ha la stessa funzionalità.
- 1. Come confrontare due hash?
- 2. Come faccio a confrontare due file in Ruby 1.9?
- 3. Come faccio a confrontare due repository git?
- 4. come confrontare due mappe hash?
- 5. Come posso assegnare due array a un hash in Perl?
- 6. Come posso unire due hash in Perl senza usare un loop?
- 7. Come faccio a confrontare due alberi sorgente in Linux?
- 8. Come faccio a confrontare due timestamp in C?
- 9. Come confrontare la data della stringa in perl?
- 10. Come faccio a confrontare due colonne nella stessa tabella?
- 11. Come faccio a confrontare tutti gli elementi di due array?
- 12. Come inserire hash in hash in Perl
- 13. Come faccio a confrontare xey in F #?
- 14. Dovrei usare $ hash {"stringa"} o $ hash {stringa} in Perl?
- 15. Come confrontare due Qstrings?
- 16. Come confrontare i valori compressi in Perl?
- 17. Come posso confrontare gli array in Perl?
- 18. Laravel ORM, data compare
- 19. mvc4 confrontare due date
- 20. Come faccio a confrontare gli oggetti in Objective-C?
- 21. Filtrare un hash di hash in perl
- 22. Come faccio a uscire da replift senza usare ctrl-d?
- 23. Come confrontare due stringhe in java senza considerare gli spazi?
- 24. Stampa hash in Perl
- 25. Come faccio a implementare l'equivalente di nidificato Perl hash in C++?
- 26. Come faccio a non importare una funzione in perl?
- 27. Come cancellare un hash Perl
- 28. Come confrontare le parti della data di due oggetti Zend_Date?
- 29. Come posso confrontare una data e un datetime in Python?
- 30. Come faccio a confrontare le versioni del registro in WiX?
Bene, si guarda in Dati :: Confronta e guarda cosa fanno. Perché non vuoi usare quel modulo? –
Possibile duplicato di [Perl - Confronta due hash nidificati] (https://stackoverflow.com/questions/37135504/perl-compare-two-ested-hash) –