• Publicidad

Hacer sort con valor de una lista

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

Hacer sort con valor de una lista

Notapor kondenado » 2006-10-08 15:30 @687

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
@nodos = (
    { id => 17, size => 300, keys => 2, cmp => 'keys' },
    { id => 14, size => 104, keys => 9, cmp => 'size' },
    { id => 31, size => 2045, keys => 43, cmp => 'keys' },
    { id => 28, size => 6, keys => 0, cmp => 'id' },
  );
Coloreado en 0.004 segundos, usando GeSHi 1.0.8.4


La idea es ordenar las tres listas según el valor de 'cmp' en cada una de ellas a través de la función sort. Lo he intentado, pero nada. Algo de ayuda por favor.

Hasta ahora he llegado a esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
use strict;

sub sort_nodes {
   my @init = @_;
   my @keys_values;
   die "you must define the array!\n" unless defined @init;
   my $count;
   foreach(@init) {
      push @keys_values, $init[$count]{'cmp'};
      $count++;
   }
   my @sorted = sort { $a cmp $b } @keys_values;
   my $elements = @sorted;
   my @final;
   for(my $i;$i<=$elements;$i++) {
      for(my $j;$j<=$elements;$j++) {
         if ($sorted[$i] eq $init[$j]{'cmp'}) {
            push @final, $init[$j];
            last;
         }
      }
   }
   return @final;
}

my @nodes = (
    { id => 17, size => 300, keys => 2, cmp => 'keys' },
    { id => 14, size => 104, keys => 9, cmp => 'size' },
    { id => 31, size => 2045, keys => 43, cmp => 'keys' },
    { id => 28, size => 6, keys => 0, cmp => 'id' },
  );

my @sorted_nodes = sort_nodes(@nodes);
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Perl programming
Avatar de Usuario
kondenado
Perlero nuevo
Perlero nuevo
 
Mensajes: 43
Registrado: 2006-08-21 18:57 @831

Publicidad

Notapor explorer » 2006-10-08 17:30 @771

El problema es cómo acceder a la estructura creada...
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

use Data::Dumper;
use warnings;
use strict;

my @nodes = (
  { id => 17, size => 300,  keys => 2,  cmp => 'keys' },
  { id => 14, size => 104,  keys => 9,  cmp => 'size' },
  { id => 31, size => 2045, keys => 43, cmp => 'keys' },
  { id => 28, size => 6,    keys => 0,  cmp => 'id'   },
);

sub sort_nodes { return sort { $a->{cmp} cmp $b->{cmp} } @_ }

my @sorted_nodes = sort_nodes(@nodes);

print Dumper @sorted_nodes;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Salida:
Código: Seleccionar todo
$VAR1 = {
          'keys' => 0,
          'cmp' => 'id',
          'id' => 28,
          'size' => 6
        };
$VAR2 = {
          'keys' => 2,
          'cmp' => 'keys',
          'id' => 17,
          'size' => 300
        };
$VAR3 = {
          'keys' => 43,
          'cmp' => 'keys',
          'id' => 31,
          'size' => 2045
        };
$VAR4 = {
          'keys' => 9,
          'cmp' => 'size',
          'id' => 14,
          'size' => 104
        };

Explicación:
Debemos ordenar una estructura basada en un array. Dentro del array, cada elemento es un hash anónimo que contiene una serie de campos. Y queremos ordenar los elementos en función de uno de esos campos.

Para ello, usaremos la función sort, naturalmente, que ordenará un array. El acceso a los elementos será con '->' ya que, en realidad, cada elemento es una 'referencia' a un hash anónimo (sí, ya sabemos que no es una referencia como en C, pero es que no quiero decir 'puntero'). Y dentro del hash, accedemos al campo 'cmp'. Y como esos campos son alfanuméricos, usamos el comparador 'cmp' (coincidencia en el nombre :-)). La función recibe la entrada por el @_ y devuelve el último valor generado (que es otro array).

Quizás tu intento no funcione porque hay dos campos iguales ('keys'). Cuando haces el doble bucle para buscar los elementos coincidentes, no tienes en cuenta el caso de que realmente existan dos elementos (o más) con ese mismo valor de campo. Una opción podría ser eliminar los elementos de @sorted a medida que los vamos guardando en el array final.

Actualización: Agregado un 'return', que es más formal.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor kondenado » 2006-10-09 17:42 @779

¡ Gracias ! El código que has escrito me funcionó a la perfección y es más simple.

Aunque, siguiendo tu sugerencia para el código que he escrito, una vez que los elementos se van guardando en @final, puse un splice del elemento (de @sorted) en cuestión hacia otro array, pero ahora sólo me guarda uno de los dos valores iguales ('keys') :S
Perl programming
Avatar de Usuario
kondenado
Perlero nuevo
Perlero nuevo
 
Mensajes: 43
Registrado: 2006-08-21 18:57 @831

Notapor explorer » 2006-10-09 18:19 @805

Pues a mí si que me funciona con splice:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
#!/usr/bin/perl

use Data::Dumper;
use strict;

sub sort_nodes {
   my @init = @_;
   my @keys_values;
   die "you must define the array!\n" unless defined @init;
   my $count;
   foreach(@init) {
      push @keys_values, $init[$count++]{'cmp'};
   }
   my @sorted = sort { $a cmp $b } @keys_values;
   my @final;
   for(my $i;$i<@sorted;$i++) {
      for(my $j;$j<@init;$j++) {
         if ($sorted[$i] eq $init[$j]{'cmp'}) {
            push @final, splice( @init, $j, 1 );
            last;
         }
      }
   }
   return @final;
}

my @nodes = (
    { id => 17, size => 300,  keys => 2,  cmp => 'keys' },
    { id => 14, size => 104,  keys => 9,  cmp => 'size' },
    { id => 31, size => 2045, keys => 43, cmp => 'keys' },
    { id => 28, size => 6,    keys => 0,  cmp => 'id'   },
  );

my @sorted_nodes = sort_nodes(@nodes);

print Dumper @sorted_nodes;
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Salida:
Código: Seleccionar todo
$VAR1 = {
          'keys' => 0,
          'cmp' => 'id',
          'id' => 28,
          'size' => 6
        };
$VAR2 = {
          'keys' => 2,
          'cmp' => 'keys',
          'id' => 17,
          'size' => 300
        };
$VAR3 = {
          'keys' => 43,
          'cmp' => 'keys',
          'id' => 31,
          'size' => 2045
        };
$VAR4 = {
          'keys' => 9,
          'cmp' => 'size',
          'id' => 14,
          'size' => 104
        };
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España

Notapor kondenado » 2006-10-09 18:48 @825

Ahora sí.
Bueno, muchas gracias por la respuesta.
Perl programming
Avatar de Usuario
kondenado
Perlero nuevo
Perlero nuevo
 
Mensajes: 43
Registrado: 2006-08-21 18:57 @831


Volver a Básico

¿Quién está conectado?

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