• Publicidad

Ordenar array bidimensional, transformada Schwartz 2ª col.

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

Ordenar array bidimensional, transformada Schwartz 2ª col.

Notapor coloradito » 2012-02-11 03:57 @206

Hola:

Tengo este array bidimensional que consigo ordenar por la primera columna,

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. __DATA__
  2. aaaa1,g,20120111-23,1
  3. aaaa3,c,20120110-3,1
  4. aaaa1,f,20120111-2,1
  5. aaaa1,g,20120111-113,1
  6. aaaa2,a,20120109-23,1
  7. aaaa2,h,20120110-3,1
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


si intento ordenarlo por la primera y tercera columna el resultado es

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
row 0:   [ aaaa1 g 20120111-113 1 ],
row 1:   [ aaaa1 f 20120111-2 1 ],
...
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


y yo esperaba que me pintase antes 20120111-2 que 20120111-113.
Tengo que hacer la ordenación alfanumérica, de ahí el problema.

¿Cómo puedo aplicar la transformada Schwartziana para la segunda columna¿ O ¿puedo implementar un substr() en el sort()?

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my @sorted
  2.     = sort {
  3.         $a->[0] cmp $b->[0] || $a->[2] cmp $b->[2]
  4.       }
  5.       @table
  6.     ;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Gracias

Código completo
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. my ( @row, @table, $n, $rowref );
  6.  
  7. while (<DATA>) {
  8.     chomp;
  9.  
  10.     # regex to separate CSV (use of a cpan module for CSV STRONGLY advised...
  11.     @row = split( /,/, $_ );
  12.  
  13.     push( @table, [@row] );            #Note the [ ] around the list
  14. }
  15.  
  16. my @sorted = sort {
  17.            $a->[0] cmp $b->[0]
  18.         || $a->[2] cmp $b->[2]
  19.  
  20. } @table;
  21.  
  22. print "\n ------------ordenada\n";
  23.  
  24. my $rowcnt = 0;
  25. foreach $rowref (@sorted) {
  26.     print "row $rowcnt: ";
  27.     $rowcnt++;
  28.     print "  [ @$rowref ], \n";
  29. }
  30.  
  31. __DATA__
  32. aaaa1,g,20120111-23,1
  33. aaaa3,c,20120110-3,1
  34. aaaa1,f,20120111-2,1
  35. aaaa1,g,20120111-113,1
  36. aaaa2,a,20120109-23,1
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
Última edición por explorer el 2012-02-11 04:58 @248, editado 1 vez en total
Razón: Formateado de código con Perltidy y poner marcas Perl
coloradito
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2012-02-09 18:51 @827

Publicidad

Re: Ordenar array bidimensional, transformada Schwartz 2ª co

Notapor coloradito » 2012-02-11 04:46 @240

Yo mismo me respondo: usando substr()

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my @sorted
  2.     = sort {
  3.         $a->[0] cmp $b->[0] || substr($a->[2],1,8) cmp substr($b->[2],1,8)
  4.         || substr($a->[2],9,) <=> substr($b->[2],9,)
  5.                
  6.       }
  7.       @table
  8.     ;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Si se os ocurre algo que sea más rápido que esto, se agradece.
Saludos
coloradito
Perlero nuevo
Perlero nuevo
 
Mensajes: 5
Registrado: 2012-02-09 18:51 @827

Re: Ordenar array bidimensional, transformada Schwartz 2ª co

Notapor explorer » 2012-02-11 05:44 @280

Un simple sort (aunque tenga muchos componentes), no es una transformada de Schwartz.

Este ejemplo sí que hace una transformada de Schwartz:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. my ( @fila, @tabla );
  7.  
  8. while (<DATA>) {                        # leemos la tabla que está en DATA
  9.     chomp;                              # fuera carácter de fin de línea
  10.  
  11.     @fila = split /,/;                  # partimos la línea por las comas
  12.  
  13.     push @tabla, [ @fila ];             # Los corchetes crean un nuevo array anónimo,
  14.                                         # cuyo contenido es la @fila,
  15.                                         # que almacenamos como nueva fila de la @tabla
  16. }
  17.  
  18. my @tabla_ordenada                      # Mi nueva tabla ordenada, será...
  19.     =
  20.     map {
  21.         $_->[2]                         # la línea original extraída del tercer componente del nuevo array
  22.     }
  23.     sort {                              # ordenada...
  24.         $a->[0] <=> $b->[0]             # por el primer componente del nuevo array...
  25.                 ||                      # o por
  26.         $a->[1] <=> $b->[1]             # el segundo componente
  27.     }
  28.     map {
  29.         [ (split /-/, $_->[2]), $_ ]    # transformamos las líneas en un nuevo array
  30.                                         # de la forma [ 20120111, 23, [aaaa1,g,20120111-23,1] ]
  31.     }
  32.     @tabla
  33.     ;
  34.  
  35. my $i = 0;
  36. print "------------desordenada\n";
  37. for my $fila_ref (@tabla) {
  38.     print "fila $i: ";
  39.     print "  [ @$fila_ref ], \n";
  40.     $i++;
  41. }
  42.  
  43. print "------------ordenada\n";
  44. $i = 0;
  45. for my $fila_ref (@tabla_ordenada) {
  46.     print "fila $i: ";
  47.     print "  [ @$fila_ref ], \n";
  48.     $i++;
  49. }
  50.  
  51. __DATA__
  52. aaaa1,g,20120111-23,1
  53. aaaa3,c,20120110-3,1
  54. aaaa1,f,20120111-2,1
  55. aaaa1,g,20120111-113,1
  56. aaaa2,a,20120109-23,1
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4
Sale:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
------------desordenada
fila 0:   [ aaaa1 g 20120111-23 1 ],
fila 1:   [ aaaa3 c 20120110-3 1 ],
fila 2:   [ aaaa1 f 20120111-2 1 ],
fila 3:   [ aaaa1 g 20120111-113 1 ],
fila 4:   [ aaaa2 a 20120109-23 1 ],
------------ordenada
fila 0:   [ aaaa2 a 20120109-23 1 ],
fila 1:   [ aaaa3 c 20120110-3 1 ],
fila 2:   [ aaaa1 f 20120111-2 1 ],
fila 3:   [ aaaa1 g 20120111-23 1 ],
fila 4:   [ aaaa1 g 20120111-113 1 ],
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

En este ejemplo, sacamos el tercer elemento de cada fila, y lo partimos por el guion, con split(). Eso nos genera dos componentes, que junto con toda la fila original como tercer componente, formamos un nuevo array de tres elementos (con los corchetes []). Luego hacemos el sort de esos nuevos array, usando comparaciones numéricas ascendentes, con la ayuda de $a, $b y '<=>'. Como son dos componentes los que tenemos que mirar, usamos '||' para unir las condiciones. Finalmente, necesitamos un map{} para "extraer" las filas originales, ahora sí ya ordenadas.
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


Volver a Básico

¿Quién está conectado?

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

cron