• Publicidad

Ordenar un arreglo de hashes

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

Ordenar un arreglo de hashes

Notapor Fegna » 2008-03-03 09:57 @456

Hola,

Ahora estoy con un problema al intentar ordenar un arreglo de hashes.

El punto es que ejecuto un procedimiento almacenado que me retorna un arreglo donde los elementos del mismo son hashes a los campos de la respuesta del procedimiento.

El código es:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
        while (my $hash_ref = $csr->fetchrow_hashref)
                {
                my $orden = $hash_ref->{'ORDENAMIENTO'};
                my $codigo_plan = $hash_ref->{'CODIGOPLAN'};
                my $nombre_plan = $hash_ref->{'NOMBREPLAN'};
                my $valor_plan = $hash_ref->{'VALORPLAN'};
                $hash_ref->{'CODIGOPLAN'} =~ s/ //g;

                push(@result, $hash_ref);
                }
 
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4


Y lo deseo ordenar por: ORDENAMIENTO, VALORPLAN, CODIGOPLAN

Lo que estaba pensando es en crear un arreglo sólo con los valores a ordenar y ordenarlos:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
                push(@result2, $orden.'|'.$valor_plan.'|'.$codigo_plan);
                @result2 = sort(@result2);
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


El punto es cómo poder leer el primer arreglo (no ordenado) utilizando los datos del segundo arreglo.

Gracias
Fegna
Perlero nuevo
Perlero nuevo
 
Mensajes: 28
Registrado: 2008-01-08 09:29 @437
Ubicación: Santiago, Chile

Publicidad

Notapor explorer » 2008-03-04 17:02 @751

Puedes guardar los valores en un array anónimo, y ese array guardarlo como elemento del array que contendrá toda la información. Luego podrás ordenarlo con un sort.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
# en el bucle
push @datos, [ $nombre, $orden, $valor_plan, $codigo_plan];

# mas tarde, ordenamos
@datos =
    sort {
        $a->[1] cmp $b->[1]
        ||
        $a->[2] cmp $b->[2]
        ||
        $a->[3] cmp $b->[3]
    }
    @datos;
 
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Metemos varias comparaciones alfanuméricas cmp (o <=> si son numéricas) y las unimos con un 'or' lógico (si falla una comparación es que son iguales y debe pasar a usar la siguiente comparación).
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14486
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor Fegna » 2008-03-06 09:47 @449

Gracias explorer por la respuesta, me guiaste por el camino.

La solución aplicada fue:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
sub ordena_planes($)
        {
        my ($ref_trae) = @_;
       
        my (@trae, @result3,
                %ref_plan,
                $cplan, $valor, $j);

        @trae = @{$ref_trae};
        $j = 0;
       
        for (my $i = 1; $i < 4; $i++)
        {
                my (%c_plan, @result2);
                foreach my $res (@trae)
                {
                        next if ($res->{'ORDENAMIENTO'} ne $i);
                        my $cod = $res->{'CODIGOPLAN'};
                        $cod =~ s/ //g;
                        my $valor = $res->{'VALORPLAN'};
                        $valor =~ s/[^\d,]//g;
                        $c_plan{$valor} .= "$cod,";
                        $ref_plan{$cod} = $res;
                        $j = 0;
                        foreach $cplan (split(/,/, $c_plan{$valor}))
                        {
                                $j ++;
                        }
                        if ($j eq 1)
                        {
                                push(@result2, $valor);
                        }
                }
                @result2 = sort @result2;
                @result2 = sort {$a <=> $b} @result2;
                foreach my $res3 (@result2)
                {
                        foreach $cplan (split(/,/, $c_plan{$res3}))
                        {
                                push(@result3, $ref_plan{$cplan});
                        }
                }
        }
        return (@result3)
 
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Si algún purista me señala que es innecesario realizar 2 sort, lo hice porque no me ordenaba bien la respuesta, dejando cifras menores después de las mayores (la línea que agregue fue el primer sort)

Otra oscuridad del software.

La publico por si alguno, alguna vez, llega a necesitar algo así (el resultado se puede ver en http://www.consalud.cl/cgi-bin/clientes/Simulador/Simula.cgi.

El ciclo for inicial lo realicé porque la respuesta recibida tenía un orden (1,2 y 3) y debía mantenerlo, por lo que ordeno lo que está en cada uno de ellos por separado y lo voy dejando en el array de respuesta.

Nuevamente, gracias Explorer
Fegna
Perlero nuevo
Perlero nuevo
 
Mensajes: 28
Registrado: 2008-01-08 09:29 @437
Ubicación: Santiago, Chile


Volver a Básico

¿Quién está conectado?

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

cron