Tengo una serie de hashes de aproximadamente 300 elementos hash:
@whole = [
{
'id' => 112,
'name' => 'Wheelbase',
'lang' => 'en'
},
{
'lang' => 'en',
'name' => 'Width',
'id' => 57
},
{
'lang' => 'en',
'id' => 174,
'name' => 'WLAN'
},
{
'id' => 252,
'name' => 'Zoom System',
'lang' => 'en'
};
];
Quiero buscar varios nombres de claves en la estructura de datos anterior con varios nombres almacenados en otra matriz.
@props = ('Price', 'Market Dominance', 'Market Capitalization');
Y mi código es:
use strict;
use warnings;
my (@matching_items, @whole); # input arrays both
my $id_prop;
@matching_items = grep {
foreach my $in (@props) {
if ($_->{name} =~ /^$in$/i) {
$id_prop = $_->{id};
print "$id_prop\n";
}
}
} @whole;
print Dumper @matching_items;
que no completa los elementos coincidentes en @matching_items. Vuelve vacío e imprime solo la identificación en la consola. ¿Qué estoy haciendo mal?
2
El bloque de código grep debe evaluarse a un valor verdadero para aceptar ese elemento de la lista.
-Shawn
28 de marzo de 2021 a las 10:54
Entonces, ¿cómo puedo modificar mi código para reflejar el valor real?
-P_Z
28/03/2021 a las 11:27
------------------------------------
Aquí hay otro enfoque:
my @whole = (
{
'id' => 112,
'name' => 'Wheelbase',
'lang' => 'en'
},
{
'lang' => 'en',
'name' => 'Width',
'id' => 57
},
);
my %props = map {$_ => 1} ('Width', 'Market Dominance', 'Market Capitalization');
my @matching_items = grep { exists $props{$_->{name}} } @whole;
12
Tu código esCorto y cercano a una sola línea. ¿Puedes explicar qué está haciendo (las dos últimas líneas)?
-P_Z
29/03/2021 a las 17:36
Se crea un hash y luego se busca en la matriz grande el nombre de entrada que existe en el hash y los que coinciden se envían a la matriz coincidente. Vaya, gracias.
-P_Z
29/03/2021 a las 17:51
Ok, acepto esta solución. Tengo una pequeña modificación si puedes hacerla. ¿Se puede modificar este código para generar una notificación/impresión en la consola de que no se encontraron elementos/claves específicas en el hash pequeño ingresado (%props), además de coincidir?
-P_Z
3 de abril de 2021 a las 9:29
Los que coincidan irán a @matching_items mientras que los que no coincidan se imprimirán.
-P_Z
3 de abril de 2021 a las 9:31
¿Quieres decir así?
– Håkon Hæglándula
3 de abril de 2021 a las 13:23
------------------------------------
Estás asignando un literal de referencia a @whole, lo cambié a una matriz. El foreach anidado se puede escribir más fácilmente usando List::Util::any, que creará un acceso directo al primer elemento que hace que el bloque se evalúe como verdadero. También puse en minúsculas tus entradas @props una vez antes del bucle y usé eq para comparar con las cadenas de nombres en minúsculas:
use strict;
use warnings;
use List::Util qw/any/;
use Data::Dumper;
use 5.016;
my @whole = (
{
'id' => 112,
'name' => 'Wheelbase',
'lang' => 'en'
},
{
'lang' => 'en',
'name' => 'Width',
'id' => 57
},
{
'lang' => 'en',
'id' => 174,
'name' => 'WLAN'
},
{
'id' => 252,
'name' => 'Zoom System',
'lang' => 'en'
}
);
my @props = ('Price', 'Market Dominance', 'Market Capitalization','Zoom System');
my @props_lc = map {lc} @props;
my @matching_items = grep {
my $name = lc $_->{name};
any {$name eq $_} @props_lc;
} @whole;
print Dumper @matching_items;
2
¿La biblioteca List::Util viene en la instalación predeterminada de Perl? No quiero instalar ninguna biblioteca para una tarea tan pequeña, especialmente en Perl debido a sus poderosas capacidades de análisis de datos.
-P_Z
29/03/2021 a las 17:35
1
List::Util está en el núcleo.
- abrazadera
29/03/2021 a las 17:40