Puede probar Arrays::Utils
, y lo hace parecer agradable y simple, pero no está haciendo magia poderosa en el back-end. Aquí está el código array_diffs
:
sub array_diff(\@\@) {
my %e = map { $_ => undef } @{$_[1]};
return @{[ (grep { (exists $e{$_}) ? (delete $e{$_}) : (1) } @{ $_[0] }), keys %e ] };
}
Desde Arrays::Utils
no es un módulo estándar, es necesario preguntarse si vale la pena el esfuerzo de instalar y mantener este módulo.De lo contrario, está muy cerca de la respuesta de DVK.
Hay ciertas cosas que debe tener en cuenta, y debe definir lo que desea hacer en ese caso particular. Digamos:
@array1 = qw(1 1 2 2 3 3 4 4 5 5);
@array2 = qw(1 2 3 4 5);
¿Estas matrices son las mismas? O, ¿son diferentes? Tienen los mismos valores, pero hay duplicados en @array1
y no en @array2
.
¿Qué tal esto?
@array1 = qw(1 1 2 3 4 5);
@array2 = qw(1 1 2 3 4 5);
diría que estas matrices son los mismos, pero Array::Utils::arrays_diff
ve de otro modo. Esto se debe a que Array::Utils
asume que no hay entradas duplicadas.
Y, aunque el Perl FAQ señalado por mob también dice que Se supone que cada elemento es único en una matriz dada. ¿Es esta una suposición que puedes hacer?
No importa qué, los hashes son la respuesta. Es fácil y rápido buscar un hash. El problema es qué quieres hacer con valores únicos.
Aquí es una solución sólida que asume duplicados no importan:
sub array_diff {
my @array1 = @{ shift() };
my @array2 = @{ shift() };
my %array1_hash;
my %array2_hash;
# Create a hash entry for each element in @array1
for my $element (@array1) {
$array1_hash{$element} = @array1;
}
# Same for @array2: This time, use map instead of a loop
map { $array_2{$_} = 1 } @array2;
for my $entry (@array2) {
if (not $array1_hash{$entry}) {
return 1; #Entry in @array2 but not @array1: Differ
}
}
if (keys %array_hash1 != keys %array_hash2) {
return 1; #Arrays differ
}
else {
return 0; #Arrays contain the same elements
}
}
Si duplicados son importantes, necesitará una manera de contarlos. Aquí está el mapa no sólo para crear un hash introducido por cada elemento de la matriz, sino también contar los duplicados en la matriz:
my %array1_hash;
my %array2_hash;
map { $array1_hash{$_} += 1 } @array1;
map { $array2_hash{$_} += 2 } @array2;
Ahora, usted puede ir a través de cada hash y verificar que no sólo existen las claves , pero que sus entradas coinciden
for my $key (keys %array1_hash) {
if (not exists $array2_hash{$key}
or $array1_hash{$key} != $array2_hash{$key}) {
return 1; #Arrays differ
}
}
Sólo se sale del bucle si todas las entradas en %array1_hash
que coincida con sus correspondientes entradas en %array2_hash
. Ahora, debe mostrar que todas las entradas en %array2_hash
también coinciden con sus entradas en %array1_hash
, y que %array2_hash
no tiene más entradas. Afortunadamente, podemos hacer lo que hicimos antes:
if (keys %array2_hash != keys %array1_hash) {
return 1; #Arrays have a different number of keys: Don't match
}
else {
return; #Arrays have the same keys: They do match
}
Tal vez puede publicar el código real de bucle anidado que' Hasta ahora, eso nos ayudará a ayudarlo a encontrar una mejor manera (si es que hay una). –
Si yo fuera tú, comenzaría con CPAN. Echar un vistazo a la lista ':: Compare' - y, sobre todo, la sección en la parte inferior "Si te gusta Lista :: comparar, te va a encantar ..." Parece que es posible que desee buscar algo implementado en C en lugar que puro Perl. http://search.cpan.org/perldoc/List::Compare – Telemachus
¿Quiere decir que usted necesita saber si una matriz es un subconjunto del otro? O si son exactamente iguales? O si tienen los mismos elementos, pero en un orden diferente? ¿Y necesitas saber qué elementos faltan o simplemente que no son lo mismo? – Schwern