¿Cómo almaceno un valor duplicado de una matriz o hash en Perl?
-
05-07-2019 - |
Pregunta
Hagamos esto muy fácil. Lo que quiero:
@array = qw/one two one/;
my @duplicates = duplicate(@array);
print "@duplicates"; # This should now print 'one'.
¿Cómo imprimir valores duplicados de una matriz / hash?
Solución
sub duplicate {
my @args = @_;
my %items;
for my $element(@args) {
$items{$element}++;
}
return grep {$items{<*>} > 1} keys %items;
}
Otros consejos
# assumes inputs can be hash keys
@a = (1, 2, 3, 3, 4, 4, 5);
# keep count for each unique input
%h = ();
map { $h{<*>}++ } @a;
# duplicate inputs have count > 1
@dupes = grep { $h{<*>} > 1 } keys %h;
# should print 3, 4
print join(", ", sort @dupes), "\n";
La versión extra verbosa y extra legible de lo que quiere hacer:
sub duplicate {
my %value_hash;
foreach my $val (@_) {
$value_hash{$val} +=1;
}
my @arr;
while (my ($val, $num) = each(%value_hash)) {
if ($num > 1) {
push(@arr, $val)
}
}
return @arr;
}
Esto se puede reducir considerablemente, pero intencionalmente lo dejé detallado para que puedas seguirlo.
Sin embargo, no lo probé, así que ten cuidado con mis errores tipográficos.
Use un diccionario, ponga el valor en la clave y el recuento en el valor.
Ah, acabo de notar que has etiquetado como perl
while ([...]) { $hash{[dbvalue]}++ }
No especificado en la pregunta es el orden en que deben devolverse los duplicados.
Puedo pensar en varias posibilidades: no me importa; por orden de primera / segunda / última aparición en la lista de entrada; ordenado.
¡Voy a jugar golf!
sub duplicate {
my %count;
grep $count{ ¡Voy a jugar golf!
<*>}++, @_;
}
@array = qw/one two one/;
my @duplicates = duplicate(@array);
print "@duplicates"; # This should now print 'one'.
# or if returning *exactly* 1 occurrence of each duplicated item is important
sub duplicate {
my %count;
grep ++$count{ ¡Voy a jugar golf!
<*>} == 2, @_;
}