Foros del Web » Programando para Internet » Javascript »

Valores "apilados" me dan error

Estas en el tema de Valores "apilados" me dan error en el foro de Javascript en Foros del Web. Buenas, Tengo una función recursiva en JavaScript, que es llamada varias veces desde otra, creando una pila de llamadas (llego a contar 17 como máximo, ...
  #1 (permalink)  
Antiguo 22/12/2013, 03:16
 
Fecha de Ingreso: abril-2012
Ubicación: 41°37′00″N, 00°37′00″E
Mensajes: 462
Antigüedad: 12 años
Puntos: 33
Valores "apilados" me dan error

Buenas,

Tengo una función recursiva en JavaScript, que es llamada varias veces desde otra, creando una pila de llamadas (llego a contar 17 como máximo, lo que no debería ser problema).

Os dejo un "snippet" de mis funciones:

La llamada "inicial" es esta (por ejemplo: fill(new Array("uno", "dos", "tres"), doc);

Código Javascript:
Ver original
  1. this.fill=function(currnode,doc){
  2.         for(i1=0;i1<currnode.length;i1++){
  3.             this.treat(doc.getElementsByTagName(currnode[i1]),currnode[i1]);
  4.         }
  5.  
  6.         return this.check();
  7. };


La función treat:
Código Javascript:
Ver original
  1. this.treat=function(nl,kindnode){
  2.         for(i2=0;i2<nl.length;i2++){
  3.             this._add(nl.item(i2), kindnode);
  4.         }
  5. };

la función _add (un ejemplo):

Código Javascript:
Ver original
  1. this._add=function(n,kind){
  2.         if(kind=="uno"){
  3.                 this.add(new Array("one", "two", "five", "ten"), n.childNodes, "uno", false);
  4.         }else if(kind=="dos"){
  5.                 this.otraFuncion(n);
  6.         }else if(kind=="uno:one"){
  7.                 this.add(new Array("pera", "manzana", "tomate", "sandía"), n.childNodes, "comida", true);
  8.         }else if(kind=="comida:pera"){
  9.                 this.tratarFruta(n.firstChild.nodeValue);
  10.         }
  11. };

Finalmente, "add":
Código Javascript:
Ver original
  1. this.add=function(fields,e,space,deep){
  2.                 for(i5=0;i5<fields.length;i5++){
  3.                         for(j=0;j<e.length;j++){
  4.                                 if(e.item(j).nodeName==fields[i5]){
  5.                                         if(deep){
  6.                                                 this._add(e.item(j).firstChild, space+":"+fields[i5]);
  7.                                         }else{
  8.                                                 this._add(e.item(j), space+":"+fields[i5]);
  9.                                         }
  10.  
  11.                                         break;
  12.                                 }
  13.                         }
  14.                 }
  15.         };

Esto en JAVA me servía como "parser" de XML perfectamente... pero en JS tengo el siguiente problema:

como habéis visito, cada bucle tiene un índice específio (iX) ya que si todos eran "i" el valor de "i" se mantenía, por lo que el siguiente bucle no empezaba por 0. Esta parte es un poco "parche de caca" pero es una solución rápida.

El problema grande me viene (de momento) con "this.add".

Si la primera llamada tiene como parámetro (por ejemplo) un array de 5 posiciones, y la segunda llamda (quedando la primera en la pila, entiendo) tiene un array de 3 posiciones, pasa algo como:

Llamada 1: i5 = 0
Llamada 1: i5 = 1
(put Llamada 1)
Llamada 2: i5 = 0
Llamada 2: i5 = 1
(put Llamada 2)
otraFuncion
[...]
(pop Llamada 2)
Llamada 2: i5 = 2
Llamada 2: i5 = 3
(pop Llamada 1)
Llamada 1: i5 = 3
(debería ser i5 = 1)

Y entonces me va saltando items porque no me recupera el valor como si tuviese apiladas las llamadas...

¿Alguien sabe qué puedo hacer?

Gracias!
  #2 (permalink)  
Antiguo 22/12/2013, 16:03
 
Fecha de Ingreso: abril-2012
Ubicación: 41°37′00″N, 00°37′00″E
Mensajes: 462
Antigüedad: 12 años
Puntos: 33
Respuesta: Valores "apilados" me dan error

Cuando he publicado el topic no estaba muy inspirado...

Después de un rato en plena inspiración he encontrado un modo bastante decente de llevar a cabo mi función:

Para ello, primero he cambiado las variables del objeto:

Código Javascript:
Ver original
  1. var miObjeto = function(){
  2.         /*aquí variables que ya habían*/
  3.         this.stackI5 = new Array();
  4.         this.stackJ = new Array();
  5.         this.stackI5I = 0;
  6.         this.stackJI = 0;
  7. }

Fialmente, emulamos un "stack", tal que:

Código Javascript:
Ver original
  1. this.add=function(fields,e,space,deep){
  2.         this.stackI5I++;
  3.         this.stackJI++;
  4.         this.stackI5[this.stackI5I] = 0;
  5.         this.stackJ5[this.stackJI] = 0;
  6.  
  7.         for(this.stackI5[this.stackI5I]=0;this.stackI5[this.stackI5I]<fields.length;this.stackI5[this.stackI5I]++){
  8.                 for(this.stackJ5[this.stackJI]=0;this.stackJ5[this.stackJI]<e.length;this.stackJ5[this.stackJI]++){
  9.                         if(e.item(this.stackJ5[this.stackJI]).nodeName==fields[this.stackI5[this.stackI5I]]){
  10.                                 if(deep){
  11.                                         this._add(e.item(this.stackJ5[this.stackJI]).firstChild, space+":"+fields[this.stackI5[this.stackI5I]]);
  12.                                 }else{
  13.                                         this._add(e.item(this.stackJ5[this.stackJI]), space+":"+fields[this.stackI5[this.stackI5I]]);
  14.                                 }
  15.  
  16.                                 break;
  17.                         }
  18.                 }
  19.         }
  20.  
  21.         this.stackI5[this.stackI5I] = 0;
  22.         this.stackJ5[this.stackJI] = 0;
  23.         this.stackI5I--;
  24.         this.stackJI--;
  25. };

De aquí a destacar:

* El código antiguo simplemente sustituye "i5" por "this.stackI5[this.stackI5I", y "j" por "this.stackJ[this.stackJI]".
* El separar el incremento y decremento de los índices en separado es para evitar warnings en el JS-Lint
* El devolver los contadores a 0 antes de decrementar es para evitar que se acumule "basura" (para que no guarde valores distintos a 0 cuando acabe el bucle).

Dejo esto aquí como referencia a quién le pudiese servir.

Un saludo.

Etiquetas: funcion, js
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 15:30.