• Publicidad

Borrar elemento de array en función recursiva

Así que programas sin strict y las expresiones regulares son otro modo de hablar. Aquí encontrarás respuestas de nivel avanzado, no recomendable para los débiles de corazón.

Borrar elemento de array en función recursiva

Notapor danimera » 2013-02-02 11:50 @535

Tengo una función recursiva que me genera un árbol según un array de id que le paso.

El problema es que esos id, pueden ser hijos o padres de otros, así que no quiero que se me repitan en el árbol pues no tiene sentido...

Lo que quiero es eliminar de mi $data principal los elementos que ya la función recursiva haya leído. Este es más o menos mi ejemplo:

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. sub categoryTreeMecaE{
  2.     my $self = shift;
  3.  
  4.     my $dbh = $self->dbh;
  5.     my $data = shift;
  6.     my $id_conf = shift;
  7.      our @ids_meca; # usado para que verificar que no se repitan mecanismos en el árbol
  8.     my $childs;
  9.     my $i  = 0;
  10.  
  11.     foreach my $d(@$data){
  12.         my $ID =    $d->{id_mecanismo};
  13.         if (grep (/$ID/,@ids_meca)){
  14.             splice(@$data, $i, 1);
  15.                 next;
  16.         };
  17.         $i++;
  18.  
  19.         push  @ids_meca,$d->{id_mecanismo};
  20.         my $childs = $category->get('mecanismo');
  21.         if( $childs ){
  22.                 $childs = $self->categoryTreeMecaE($childs,$id_conf);
  23.             $d->{data}->{'childs'} = $childs;
  24.         }
  25.     }
  26.     return  $data;
  27. }
Coloreado en 0.002 segundos, usando GeSHi 1.0.8.4


Lo que trato de hacer, y ojalá con el mismo foreach(), es:
con push @ids_meca,$d->{id_mecanismo}; guardo el id del mecanismo en una variable global. Cuando la función retorna con otro elemento del array busca si ya se ha leído algún elemento con el mismo id if (grep (/$ID/,@ids_meca)) y ahí es donde necesito borrar del $data, con splice(), con lo que sea, pero que sea con un foreach()... :S NO sé si me hice entender...

Igual eliminé cosas de la función que no necesitaba para que fuera más claro.
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: Borrar elemento de array en función recursiva

Notapor explorer » 2013-02-02 14:12 @633

El recordar si las cosas han aparecido una vez es cosa de los hash.

En lugar de usar un array, mete los id como claves, y como valor, una referencia a la estructura de ese id.

Luego... a la hora de crear el árbol o de podarlo, si un id aparece como repetido, destruimos la rama duplicada con tan solo asignar a su nodo padre la referencia que también nos da el hash. De esta manera, el nodo padre apunta al mismo sitio que el id primero.

Ahora bien... tu lo que quieres no es simplificar ramas, sino simplemente destruir las duplicadas... en lugar de splice(), prueba a usar delete(), que también sirve para eliminar elementos dentro de un array, que parece que es la estructura que estás usando para hacer el árbol.

Hacer un splice() dentro del mismo for() que recorre el array no es nada aconsejable.

También, delete() no reducirá el tamaño del array si eliminas elementos que estén en mitad de él, solo si eliminas los elementos del final del array. delete() deja los elementos con un valor de 'inexistencia' (quiere decir que si haces un exists($data->[$i]) devolverá falso). Cuando termines la poda, puedes quitar esos elementos inexistentes con otro grep{exists()} map @$data, a un nuevo array, que será el nuevo valor de $data.
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: Borrar elemento de array en función recursiva

Notapor danimera » 2013-02-02 14:53 @661

Primero:

La función recibe un resultado de una query que me trae unos registro de la base de datos, esos datos son los que le paso a la función que genera el árbol... pero algunos de esos registros son hijos de otro mismo registro del resultado del query.

Después ese resultado del árbol va a una función que me genera un html...

Por lo anterior no podré cambiar mi estructura de datos, tendría que hacer algo que me depurara, así me toque recorrer de nuevo el árbol comparando con un listado externo...

Ahí envío la imagen:
Adjuntos
ARBOL.png
es el resultado del árbol
ARBOL.png (71.37 KiB) Visto 2985 veces
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: Borrar elemento de array en función recursiva

Notapor danimera » 2013-02-02 15:06 @671

Bueno, usando el código que pegué solo hice una modificación en el $i++ después del next, tengo que tenerlo de todas formas antes del next, para que pueda tener correctamente el índice.

Hasta ahora parece todo andar bien.

Sintáxis: [ Descargar ] [ Ocultar ]
Using perl Syntax Highlighting
  1. if ( grep ( /$ID/, @ids_meca ) ) {
  2.  
  3.     splice( @$data, $i, 1 );
  4.     $i++                               # HACÍA FALTA ÉSTE AQUÍ
  5.     next;
  6. }
  7.  
  8. $i++;
  9.  
Coloreado en 0.001 segundos, usando GeSHi 1.0.8.4
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


Volver a Avanzado

¿Quién está conectado?

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