FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveWin para Harbour/xHarbour HASH con uno de los key que es un array
Posts: 563
Joined: Sun Oct 09, 2005 07:23 PM
HASH con uno de los key que es un array
Posted: Fri Nov 28, 2025 04:41 PM

Buenas tardes, Me estoy encontrando con un problema que no entiendo con un hash. Mi problema consiste en que el único valor del hash que no es correcto es el que es un array. Porque cuando acaba el bucle siempre muestra los valores de la última asignación que le hecho dentro del mismo. Es como si tomara la referencia a la posición de memoria del array que se le asigna en vez de los valores que contiene.

En un bucle hago algo como lo siguiente: aSalida:={} aIntervenciones:={} //array hDatos:={=>} //hash

do while hDatos["nombre"]=DBF->NOMBRE hDatos["calle"]=DBF->CALLE hDatos["intervenciones"]={} //Resetea las intervenciones para el nuevo nombre while DBF->NOMBRE == hDatos["nombre" aadd(aIntervenciones, DBF->NUMINTERV) DBF->(dbskip(+1)) enddo //Graba los datos aadd(aSalida, hDatos) enddo

xbrowse(aSalida) // Muestra distintos todos los valores del hash como hDatos["nombre"] y hDatos["calle"], pero el valor de hDatos["intervenciones"] es el mismo para todos e igual al del último registro que se procesó en el bucle.

Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: HASH con uno de los key que es un array
Posted: Fri Nov 28, 2025 05:12 PM

El objetivo del código parece ser procesar un archivo de base de datos (DBF) para agrupar las intervenciones por nombre y almacenarlas en un array de salida.

Aquí tienes la corrección y explicación.

🛠️ Código Corregido

Suponiendo que el bucle exterior es el que itera a través de todos los registros del archivo DBF (algo que el fragmento original omite), esta es la estructura correcta del bucle DO WHILE/ENDDO:

// Bucle exterior: Itera a través de todos los registros del DBF
DO WHILE !Eof()

    // 1. Inicializar el hash de datos para el nombre actual
    hDatos := {} // Inicializa un nuevo hash para el registro actual
    hDatos["nombre"] := DBF->NOMBRE
    hDatos["calle"] := DBF->CALLE
    hDatos["intervenciones"] := {} // Array para almacenar las intervenciones

    // 2. Bucle interior: Recorre todos los registros que tengan el mismo nombre
    // Se usa un DO WHILE o un WHILE más simple, ya que el primer registro ya es el nombre correcto
    WHILE !Eof() .AND. DBF->NOMBRE == hDatos["nombre"]
        
        // Agregar el número de intervención al array del hash
        AADD(hDatos["intervenciones"], DBF->NUMINTERV)
        
        // Mover al siguiente registro
        DBF->(DBSKIP(+1))
    
    ENDDO // Fin del WHILE interior (mismo nombre)

    // 3. Grabar los datos agrupados
    AADD(aSalida, hDatos)

ENDDO // Fin del DO WHILE exterior (fin de archivo)

🔍 Errores y Explicación

Los principales errores en tu código original eran:

  1. Sintaxis Incompleta en el WHILE:

    • Original: while DBF->NOMBRE == hDatos["nombre"
    • Corrección: Faltaba el paréntesis de cierre, y lo más importante, se necesitaba la condición !Eof() (mientras no sea el fin del archivo) para evitar un error cuando se llega al final.
    • Corregido: WHILE !Eof() .AND. DBF->NOMBRE == hDatos["nombre"]
  • Uso Incorrecto del DO WHILE:

    • Original: El código usaba enddo sin un do while previo para el bucle interior. En el código xBase, un bucle WHILE se cierra con ENDDO o ENDIF (dependiendo de la versión o dialecto), pero la estructura DO WHILE ... ENDDO tiene una semántica específica que implica un bucle. En el código corregido, se usa el WHILE ... ENDDO estándar para el bucle de agrupamiento.

  • Variable aIntervenciones no Definida:

    • Original: aadd(aIntervenciones, DBF->NUMINTERV)

    • Corrección: El array de intervenciones estaba siendo reseteado en el hash (hDatos["intervenciones"]={}) pero se intentaba añadir el dato a una variable diferente (aIntervenciones). El dato debe añadirse al array que está dentro del hash: AADD(hDatos["intervenciones"], DBF->NUMINTERV).
  • Inicialización de hDatos:

    • Para cada nuevo grupo de nombres, debes inicializar un nuevo hash. La línea hDatos := {} (que faltaba) asegura que no se sobrescriban los datos del registro anterior.

  • regards, saludos

    Antonio Linares
    www.fivetechsoft.com
    Posts: 563
    Joined: Sun Oct 09, 2005 07:23 PM
    Re: HASH con uno de los key que es un array
    Posted: Fri Nov 28, 2025 06:07 PM

    Gracias Antonio.

    Al final lo que lo ha arreglado era hacer un hb_clone(hashAcopiar)

    Continue the discussion