• Publicidad

Ordenar hash por valor

¿Apenas comienzas con Perl? En este foro podrás encontrar y hacer preguntas básicas de Perl con respuestas aptas a tu nivel.

Ordenar hash por valor

Notapor fgalves » 2007-09-14 09:55 @455

Hola a todos,

Estoy bloqueado con un problema relacionado con la ordenación de un hash.

Tengo un hash de dos niveles, algo como:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
%mihash = {
'llave1' => { 'subllave1' => valor1,
                  'subllave2' => valor2,
                  'subllave3' => valor3},
'llave2' => { 'subllave1' => valor1,
                  'subllave2' => valor2,
                  'subllave3' => valor3},
...
}
Coloreado en 0.003 segundos, usando GeSHi 1.0.8.4


El caso es que quiero escribir en un fichero el contenido de dicho hash, pero ordenado según el valor de 'subllave3' de forma decreciente.

He intentado algo como:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $key (sort {$mihash{subllave3}{$b} <=> $hash{subllave3}{$a} } keys %mihash )
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Pero no funciona...

Me imagino que debo añadir un nivel mas, algo así como:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $key (sort {$mihash{llave}{subllave3}{$b} <=> $hash{llave}{subllave3}{$a} } keys %mihash )
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Pero el problema está en que la llave primaria de mi hash es una variable $var, por lo cual no sé cómo referenciarla (es decir, no tiene un nombre conocido por el programa como "subllave3").

¿Alguien me puede echar una mano?

¡¡Un saludo!!
Felipe
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Publicidad

Notapor fgalves » 2007-09-14 10:20 @472

Hola de nuevo,

Ya dí con la solución:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $key (sort {$mihash{$b}{subllave3}<=> $mihash{$a}{subllave3}} keys %mihash
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Es la llave primaria la que cambia, y por tanto la que debía ser referida por los valores genéricos $a y $b.

¡¡Saludos a todos!!
Felipe

EDITADO POR MONOSWIM: el código decía $hash{$a}{subllave3} en vez de $mihash{$a}{subllave3}
fgalves
Perlero nuevo
Perlero nuevo
 
Mensajes: 210
Registrado: 2006-09-25 13:54 @621

Notapor Perl user » 2007-09-14 20:38 @901

fgalves escribiste:Hola de nuevo,

Ya dí con la solución:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach my $key (sort {$mihash{$b}{subllave3}<=> $hash{$a}{subllave3}} keys %mihash
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Es la llave primaria la que cambia, y por tanto la que debía ser referida por los valores genéricos $a y $b.

¡¡Saludos a todos!!
Felipe


Qué tal,

Posiblemente te estás complicando un poquito más el problema. Si piensas un poco en lo que quieres, tendrás una solución más eficiente y con mucho menos esfuerzo.

Te ayudaré a reflexionar un poco en el algoritmo:

1) Identificar qué es lo que nos sirve del hash para ordenarlo
2) Nos interesa la llave principal (nivel 1), y el valor a ordenar, el cual se obtiene de 'subllave3' (nivel 2).
3) Ordenar por medio de el valor de 'llave3', pero dejar la llave principal den algún lugar, para utilizarla después.
4) Ordenar mediante el criterio deseado (ascendente o descendente) y utilizar el operador apropiado (esto es importante).
5) Una vez ordenado, sacamos las llaves principales que almacenamos en algún lugar para así acceder al hash por ese orden, el cual es lo que queríamos cubrir.

Bien pues este algoritmo se trata del método que lleva el nombre de Randal Schwartz, conocido como Schwartzian transform, el cual consiste en obtener los datos que nos interesan (paso 1y 2), generalmente almacenados en una referencia. Luego ordenamos mediante el criterio deseado, utilizando los datos de interés (paso 3 y 4), para así al final, obtener los datos de interés en el orden establecido.

El código queda algo como esto:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
my @llaves_ordenadas =
  map  { $_->[0] }
  sort { $a->[1] cmp $b->[1] }
  map  { [$_, $hash{$_}{subllave3}] }
  keys %hash;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Al finalizar, @llaves_ordenadas tendrá las llaves principales del hash, para que lo puedas acceder mediante el orden de 'subllave3'.

Saludos,
Marco A. Manzo
[email protected]
http://www.unixmonkeys.com/amnesiac/
Perl Programming Language
Perl user
Maestro honorario
Maestro honorario
 
Mensajes: 271
Registrado: 2004-11-03 21:11 @924


Volver a Básico

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 0 invitados

cron