• Publicidad

Más problema con ordenar array

¿Ya sabes lo que es una referencia? Has progresado, el nível básico es cosa del pasado y ahora estás listo para el siguiente nivel.

Más problema con ordenar array

Notapor danimera » 2010-04-01 09:19 @430

Bueno, traigo de un fichero unos datos que me salen por medio de una función de la siguiente manera: id||nombre||privacidad. Esto es lo que arroja el Dumper:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
$VAR1 = '23||23 Baño alcoba principal||0';
$VAR2 = '22||22 Baño vestier||0';
$VAR3 = '21||21 Vestier||0';
$VAR4 = '20||20 Hall alcobas||0';
$VAR5 = '19||19 Alcoba 1||0';
$VAR6 = '18||18 Baño alcoba 1||0';
$VAR7 = '17||17 Baño alcoba 2||0';
$VAR8 = '16||16 Alcoba 2||0';
$VAR9 = '15||15 Balcon alcoba 2||0';
$VAR10 = '14||14 Balcon alcoba principal||0';
$VAR11 = '13||13 Alcoba principal||0';
$VAR12 = '12||12 Sala teatro||0';
$VAR13 = '11||11 Balcon sala teatro||0';
$VAR14 = '10||10 Comedor||0';
$VAR15 = '9||9 Corredor principal||0';
$VAR16 = '8||8 Puerta garaje||0';
$VAR17 = '7||7 Garaje||0';
$VAR18 = '6||6 Patio ropas||0';
$VAR19 = '5||5 Cocina||0';
$VAR20 = '4||4 Terraza-cocina||0';
$VAR21 = '3||3 Terraza||0';
$VAR22 = '2||2 Entrada garaje||0';
$VAR23 = '1||1 Puerta principal||0';
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Como ven lleva un orden, Luego solo quiero crear un hash ID => Nombre
de esta forma:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
foreach $registro(@categorias){

       $registro =~ s/\n//g;
       my ($id,$nombre,$privacidad) = split(/\|\|/, $registro);

        if ($privacidad == 0){

            $loop{$id} = $nombre;

        }
}
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Pero cuando hago el dumper de %loop obtengo esto:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
$VAR1 = '11';
$VAR2 = '11 Balcon sala teatro';
$VAR3 = '21';
$VAR4 = '21 Vestier';
$VAR5 = '7';
$VAR6 = '7 Garaje';
$VAR7 = '2';
$VAR8 = '2 Entrada garaje';
$VAR9 = '17';
$VAR10 = '17 Baño alcoba 2';
$VAR11 = '22';
$VAR12 = '22 Baño vestier';
$VAR13 = '1';
$VAR14 = '1 Puerta principal';
$VAR15 = '18';
$VAR16 = '18 Baño alcoba 1';
$VAR17 = '13';
$VAR18 = '13 Alcoba principal';
$VAR19 = '23';
$VAR20 = '23 Baño alcoba principal';
$VAR21 = '16';
$VAR22 = '16 Alcoba 2';
$VAR23 = '6';
$VAR24 = '6 Patio ropas';
$VAR25 = '3';
$VAR26 = '3 Terraza';
$VAR27 = '9';
$VAR28 = '9 Corredor principal';
$VAR29 = '12';
$VAR30 = '12 Sala teatro';
$VAR31 = '20';
$VAR32 = '20 Hall alcobas';
$VAR33 = '15';
$VAR34 = '15 Balcon alcoba 2';
$VAR35 = '14';
$VAR36 = '14 Balcon alcoba principal';
$VAR37 = '8';
$VAR38 = '8 Puerta garaje';
$VAR39 = '4';
$VAR40 = '4 Terraza-cocina';
$VAR41 = '19';
$VAR42 = '19 Alcoba 1';
$VAR43 = '10';
$VAR44 = '10 Comedor';
$VAR45 = '5';
$VAR46 = '5 Cocina';
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Lo anterior es que lo que no me convence... de ahí tengo que pasarlo como parámetros de un FormBuilder para que me genere una lista desplegable, pero debe quedarme en orden, por lo menos alfabéticamente. :? Honestamente, no sé qué es lo que hago mal; he intentado de todo y nada, siempre me quedan de esa forma desordenada por muchos sort() que intente.
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Publicidad

Re: Más problema con ordenar array

Notapor explorer » 2010-04-01 11:39 @527

Los valores de un hash nunca se guardan en el orden en que se almacenan.

Primer párrafo de perldata: «Perl posee tres tipos de datos básicos: escalares, arreglos de escalares, y arreglos asociativos de escalares, conocidos como "diccionarios". Un escalar es una simple cadena (de cualquier tamaño, limitada solo por la memoria disponible), número o una referencia a otra cosa (que será explicada en perlref). Arreglos normales son listas ordenadas de escalares indexadas por número, empezando por 0. Los diccionarios son colecciones desordenadas de valores escalares indexados por una cadena clave asociada al valor.»

Una vez que tienes la información en un diccionario, ahora depende de cómo quieres obtener la salida de esa información.

Si, por ejemplo, queremos verla ordenada por id, solo tendríamos que ordenar las claves, en este caso, numéricamente:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use diagnostics;
  5.  
  6. my @categorias = (
  7.     '1||1 Puerta principal||0',
  8.     '2||2 Entrada garaje||0',
  9.     '3||3 Terraza||0',
  10.     '4||4 Terraza-cocina||0',
  11.     '5||5 Cocina||0',
  12.     '6||6 Patio ropas||0',
  13.     '7||7 Garaje||0',
  14.     '8||8 Puerta garaje||0',
  15.     '9||9 Corredor principal||0',
  16.     '10||10 Comedor||0',
  17.     '11||11 Balcón sala teatro||0',
  18.     '12||12 Sala teatro||0',
  19.     '13||13 Alcoba principal||0',
  20.     '14||14 Balcón alcoba principal||0',
  21.     '15||15 Balcón alcoba 2||0',
  22.     '16||16 Alcoba 2||0',
  23.     '17||17 Baño alcoba 2||0',
  24.     '18||18 Baño alcoba 1||0',
  25.     '19||19 Alcoba 1||0',
  26.     '20||20 Hall alcobas||0',
  27.     '21||21 Vestier||0',
  28.     '22||22 Baño vestier||0',
  29.     '23||23 Baño alcoba principal||0',
  30. );
  31.  
  32. my %loop;
  33.  
  34. for my $registro (@categorias) {
  35.  
  36.     #chomp $registro;
  37.  
  38.     my ($id, $nombre, $privacidad) = split /\|\|/, $registro;
  39.  
  40.     if (not $privacidad) {
  41.         $loop{$id} = $nombre;
  42.     }
  43. }
  44.  
  45. my @indices_loop_ordenado = sort { $a <=> $b } keys %loop;  # ordenación numérica por claves
  46.  
  47. for my $clave (@indices_loop_ordenado) {
  48.  
  49.     print "$clave => $loop{$clave}\n";
  50. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4

Sale:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
1 => 1 Puerta principal
2 => 2 Entrada garaje
3 => 3 Terraza
4 => 4 Terraza-cocina
5 => 5 Cocina
6 => 6 Patio ropas
7 => 7 Garaje
8 => 8 Puerta garaje
9 => 9 Corredor principal
10 => 10 Comedor
11 => 11 Balcón sala teatro
12 => 12 Sala teatro
13 => 13 Alcoba principal
14 => 14 Balcón alcoba principal
15 => 15 Balcón alcoba 2
16 => 16 Alcoba 2
17 => 17 Baño alcoba 2
18 => 18 Baño alcoba 1
19 => 19 Alcoba 1
20 => 20 Hall alcobas
21 => 21 Vestier
22 => 22 Baño vestier
23 => 23 Baño alcoba principal
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Ahora bien, si lo que quieres es ordenarlo por los valores, y además, alfabéticamente, debemos cambiar la línea 45 por esta otra:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. my @indices_loop_ordenado = sort { $loop{$a} cmp $loop{$b} } keys %loop; # ordenación de las claves por el orden alfabético de los valores
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4


Pero... fíjate que en el $nombre que estás guardando como valor, empieza por un número:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. use Data::Dumper;
  2. print Dumper \%loop;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
$VAR1 = {
          '11' => '11 Balcón sala teatro',
          '21' => '21 Vestier',
          '7' => '7 Garaje',
          '17' => '17 Baño alcoba 2',
          '2' => '2 Entrada garaje',
          '22' => '22 Baño vestier',
          '1' => '1 Puerta principal',
          '18' => '18 Baño alcoba 1',
          '23' => '23 Baño alcoba principal',
          '16' => '16 Alcoba 2',
          '13' => '13 Alcoba principal',
          '6' => '6 Patio ropas',
          '3' => '3 Terraza',
          '9' => '9 Corredor principal',
          '12' => '12 Sala teatro',
          '20' => '20 Hall alcobas',
          '14' => '14 Balcón alcoba principal',
          '15' => '15 Balcón alcoba 2',
          '8' => '8 Puerta garaje',
          '4' => '4 Terraza-cocina',
          '19' => '19 Alcoba 1',
          '10' => '10 Comedor',
          '5' => '5 Cocina'
        };
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4

así que si quieres ordenarlos alfabéticamente, deberías antes quitarles esos números:
Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1.         $nombre =~ s/^[\d\s]+//;
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4

y ahora sí que sale bien:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
19 => Alcoba 1
16 => Alcoba 2
13 => Alcoba principal
15 => Balcón alcoba 2
14 => Balcón alcoba principal
11 => Balcón sala teatro
18 => Baño alcoba 1
17 => Baño alcoba 2
23 => Baño alcoba principal
22 => Baño vestier
5 => Cocina
10 => Comedor
9 => Corredor principal
2 => Entrada garaje
7 => Garaje
20 => Hall alcobas
6 => Patio ropas
8 => Puerta garaje
1 => Puerta principal
12 => Sala teatro
3 => Terraza
4 => Terraza-cocina
21 => Vestier
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Si, de todas maneras, necesitas que el diccionario recuerde el orden de las claves a medida de que fueron creadas, lo tienes resuelto en perlfaq4: How can I make my hash remember the order I put elements into it?
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

Re: Más problema con ordenar array

Notapor danimera » 2010-04-01 12:46 @573

Bueno, esto me parece genial, pero, honestamente, qué tonto fui: FormBuilder ya había pensando en eso y tienes las opciones de ordenar:
Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
    NAME            Sort option values by name
    NUM             Sort option values numerically
    LABELNAME       Sort option labels by name
    LABELNUM        Sort option labels numerically
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Pero por otro lado sí necesitaba esto para desplegarlo también ordenado en un loop de html-template, ahí sí no hay aun nada para eso, pero tocará retornar en un HTML impreso desde Perl.

No es claro para mi pasar un array ordenado a la plantilla de HTML::Template, pero con esto es suficiente. Gracias, explorer.
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Re: Más problema con ordenar array

Notapor marcmb » 2010-06-17 08:40 @403

Buenas de nuevo, tengo un archivo del tipo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using text Syntax Highlighting
Andrés[..]Planeta01[..][3:1:1][..]Planeta01.gif
Andrés[..]Planeta02[..][3:2:3][..]Planeta02.gif
Andrés[..]Planeta05[..][3:4:11][..]Planeta05.gif
Juan[..]JuanPrincipal[..][2:249:1][..]JuanPrincipal.gif
Juan[..]Juanito[..][2:250:9][..]Juanito.gif
Juan[..]Juanín[..][3:266:8][..]Juanín.gif
Mutante[..]Zombie[..][3:242:10][..]Zombie.gif
Mutante[..]Muerto[..][3:236:2][..]Muerto.gif
Sorpound[..]Colonia[..][1:245:13][..]Colonia.gif
Coloreado en 0.000 segundos, usando GeSHi 1.0.8.4


Y quería que cada usuario pueda añadir sus colonias desde la web, pero claro, si lo hacemos de forma normal cualquier modificación quedaría debajo de Sorpound, y lo que yo quiero hacer es que si es Andrés el que añade una colonia se añada justo después de la última colonia de Andrés, es decir, después de Planeta05.
No hace ninguna falta que me deis el código hecho, simplemente si alguien sabe de algún tutorial para hacerlo estaría muy bueno que me diga dónde encontrarlo.

Yo me imagino que debería guardar los datos después de Sorpound (como haríamos normalmente) y luego debería volver a leer los datos guardados, ordenarlos, y guardarlos de nuevo sobreescribiendo el archivo original, pero no estoy nada seguro de todo esto :P

Agradezco cualquier idea.
Avatar de Usuario
marcmb
Perlero nuevo
Perlero nuevo
 
Mensajes: 55
Registrado: 2010-05-03 07:42 @362
Ubicación: Girona

Re: Más problema con ordenar array

Notapor explorer » 2010-06-17 12:01 @542

Aunque este problema es fácil de solucionar con un módulo como Tie::File, no se me ocurriría hacer una base de datos en un fichero de texto sabiendo que puede ser modificado por varias peticiones a la vez. Puede quedar el fichero destrozado si dos o más usuarios lo modifican al mismo tiempo.

Te recomiendo que uses un motor de base de datos. SQLite estaría muy bien para una base de datos muy sencilla.
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

Re: Más problema con ordenar array

Notapor danimera » 2010-06-17 12:42 @570

No soy experto en ficheros, pero sí tengo ya mucha experiencia... y la verdad es fácil con Tie::File. Yo hice un módulo llamado kreader que permite hacer eso... Lo que podría es enviarte el módulo para que veas cómo manipulo un fichero usando algunas funciones que me permiten adicionar, editar y eliminar registros.
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Re: Más problema con ordenar array

Notapor marcmb » 2010-06-17 17:03 @752

Mira: sería bueno probar tu módulo :) Así como dices aprenderé a hacerlo yo mismo.

Referente a lo que dijo explorer es algo que quiero hacer, pero en octubre lo más probable. Ahora no tengo tiempo para dedicarle a bases de datos. Y usando flock() problema de archivo corrupto solucionado ¡je,je,je!
Avatar de Usuario
marcmb
Perlero nuevo
Perlero nuevo
 
Mensajes: 55
Registrado: 2010-05-03 07:42 @362
Ubicación: Girona

Re: Más problema con ordenar array

Notapor danimera » 2010-06-17 23:41 @029

Bueno, yo te lo envío, pero perdóname, es que mi equipo donde tengo eso no tiene conexión a Internet y he tenido mucho trabajo.
100% Telch - Perl Web Programming
Cali PerlMongers: http://cali.pm.org
Avatar de Usuario
danimera
Perlero frecuente
Perlero frecuente
 
Mensajes: 871
Registrado: 2005-06-23 19:02 @834
Ubicación: Colombia

Re: Más problema con ordenar array

Notapor explorer » 2010-06-18 02:57 @164

marcmb escribiste:Y usando flock() problema de archivo corrupto solucionado ¡je,je,je!

... que es justo lo que hace SQLite, pero de forma transparente para el programador.
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

Re: Más problema con ordenar array

Notapor marcmb » 2010-06-18 10:11 @466

Danimera, tu tranquilo que no tengo prisa ninguna, y muy agradecido por el módulo.

Explorer, gracias a ti por esa explicación. Se puede decir que solo con vuestra página uno ya puede aprender Perl, entre los tutoriales y el foro sale casi todo sobre Perl.
Avatar de Usuario
marcmb
Perlero nuevo
Perlero nuevo
 
Mensajes: 55
Registrado: 2010-05-03 07:42 @362
Ubicación: Girona

Siguiente

Volver a Intermedio

¿Quién está conectado?

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