Page 1 of 1
HASH con uno de los key que es un array
Posted: Fri Nov 28, 2025 4:41 pm
by Verhoven
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.
Re: HASH con uno de los key que es un array
Posted: Fri Nov 28, 2025 5:12 pm
by Antonio Linares
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:
Code: Select all | Expand
// 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:
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:
Inicialización de hDatos:
Re: HASH con uno de los key que es un array
Posted: Fri Nov 28, 2025 6:07 pm
by Verhoven
Gracias Antonio.
Al final lo que lo ha arreglado era hacer un hb_clone(hashAcopiar)