Page 1 of 2

Iniciandome en el manejo de tablas HASH

Posted: Mon Mar 12, 2012 11:59 am
by JmGarcia
Pues mi primer contratiempo en el manejo de tablas hash.

No se como detectar si ya existe un elemento en la tabla hash.

Supongo que una vez detectado que no existe añadir uno mas sería tan facil como esto ¿ no ?:
aHash [ cNuevaMatricula ] := Tcoche():New( cNuevaMatricula )

Code: Select all

function main()
PUBLIC hHash := {=>},cMatricula
aHash[ "M-1234-DF" ] := Tcoche():New( "M-1234-DF" )
aHash[ "V-4321-AF" ] := Tcoche():New( "V-4321-AF" )
aHash[ "B-1111-AA" ] := Tcoche():New( "B-1111-AA" )
aHash[ "O-2222-BB" ] := Tcoche():New( "O-2222-BB" )
aHash[ "L-3333-CC" ] := Tcoche():New( "L-3333-CC" )

msginfo( hScan ( aHash , "O-2222-BB" ) ) // Me da siempre 0

return nil

**************************************************************************

CLASS Tcoche
   DATA cMatricula,cMarca,nPrecio
   CLASSDATA lRegistered AS LOGICAL
   METHOD New ( cIndicativo ) CONSTRUCTOR
   METHOD End()
ENDCLASS

METHOD New ( cMatricula ) CLASS Tcoche
DEFAULT cMatricula:="X-9999-XX"
::cMatricula:=cMatricula
::cMarca:="¿?"
::nPrecio:=0
return Self

METHOD End() CLASS Tcoche
::cMatricula:=""
::cMarca:=""
::nPrecio:=-1
return .T.
Supongo que la inicializacion de la tabla se puede hacer de esta forma:

Code: Select all

PUBLIC hHash := {=>}
aHash[ "M-1234-DF" ] := Tcoche():New( "M-1234-DF" )
aHash[ "V-4321-AF" ] := Tcoche():New( "V-4321-AF" )
aHash[ "B-1111-AA" ] := Tcoche():New( "B-1111-AA" )
aHash[ "O-2222-BB" ] := Tcoche():New( "O-2222-BB" )
aHash[ "L-3333-CC" ] := Tcoche():New( "L-3333-CC" )
 
o de esta otra forma:

Code: Select all

PUBLIC hHash := {"M-1234-DF" => Tcoche():New("M-1234-DF"),;
                 "V-4321-AF" => Tcoche():New( "V-4321-AF" ),;
                 "B-1111-AA" => Tcoche():New( "B-1111-AA" ),;
                 "O-2222-BB" => Tcoche():New( "O-2222-BB" ),;
                 "L-3333-CC" => Tcoche():New( "L-3333-CC" )} 

Re: Iniciandome en el manejo de tablas HASH

Posted: Mon Mar 12, 2012 12:48 pm
by MarioG
JM;
Con xHarbour lo haría así:

Code: Select all

aHash:= Hash( "M-1234-DF", "M-1234-DF", ;
              "V-4321-AF", "V-4321-AF", ;
              "B-1111-AA", "B-1111-AA", ;
              "O-2222-BB", "O-2222-BB", ;
              "L-3333-CC", "L-3333-CC" )

if "M-9999-DF" IN aHash
   ? "Existe"
else
   ? "No existe"
   aHash["M-9999-DF"]:= "M-9999-DF"
end
HEval( aHash, {|cKey,cVal| wqout({cKey,cVal}) })   // Algo llamativo, el orden NO es el arriba asignado (??)
msginfo( hScan ( aHash , "M-9999-DF" ) ) // me devuelve 4; como veras no lo adiciona a la última posición
Saludos

Re: Iniciandome en el manejo de tablas HASH

Posted: Mon Mar 12, 2012 6:28 pm
by JmGarcia
Gracias MarioG.

Yo lo que quiero es que el contenido de la tabla sean OBJETOS de la clase Tcoche y el indice sea la mátricula.

Eso es lo que buscaba if "M-9999-DF" IN aHash como detectar si existe un elemento en la tabla.

Probare esto.

Re: Iniciandome en el manejo de tablas HASH

Posted: Mon Mar 12, 2012 9:11 pm
by Antonio Linares
JM,

Asi debería servir:

Code: Select all

if aHash[ "O-2222-BB" ] == nil
   MsgInfo( "no existe" )
else
   MsgInfo( "existe" )
endif
 

Re: Iniciandome en el manejo de tablas HASH

Posted: Tue Mar 13, 2012 2:02 pm
by JmGarcia

Code: Select all

if aHash[ "O-2222-BB" ] == nil
Me da este error: Error description: Error BASE/1132 Bound error: array access

Re: Iniciandome en el manejo de tablas HASH

Posted: Tue Mar 13, 2012 2:17 pm
by sambomb

Code: Select all

Try
   if aHash[ "O-2222-BB" ] == nil
      MsgInfo( "no existe" )
   else
      MsgInfo( "existe" )
   endif
catch
   MsgInfo("no existe")
end
 

Re: Iniciandome en el manejo de tablas HASH

Posted: Tue Mar 13, 2012 2:25 pm
by jcenteno
HHasKey( aHash, "O-2222-BB" ) --> lExists

Re: Iniciandome en el manejo de tablas HASH

Posted: Tue Mar 13, 2012 2:40 pm
by MarioG

Code: Select all

if "M-9999-DF" IN aHash
...
funciona!
disculpen que insista, pero yo me tropece con el problema hace bastante y es lo que me da buen resultado.
Lo que indica jcenteno tambien es otra opcion factible

Saludos

Re: Iniciandome en el manejo de tablas HASH

Posted: Tue Mar 13, 2012 6:37 pm
by JmGarcia
Gracias Sambomb, buena idea. Pero es una salida de un error y puede que tardar mas tieempo de ejecucion que if "O-2222-BB" IN aHash. Tengo que hacerlo en iteraciones de un programa en tiempo real que recibe mas de 300 mensajes TCP/UDP por segundo.

Me queda otra duda, ¿ como recorro la tabla ?

Code: Select all

for i=1 to len(aHash)
   ? aHash[i] // me da error "array access"
next i

Re: Iniciandome en el manejo de tablas HASH

Posted: Tue Mar 13, 2012 8:31 pm
by MarioG
JM;
mas arriba, en el post que te escribí está

Re: Iniciandome en el manejo de tablas HASH

Posted: Tue Mar 13, 2012 9:32 pm
by JmGarcia
Para 10 millones de iteraciones es mas rápida la sentencia "IN" que la función "HHasKey"

Esta tarda 34,84 seg.
jcenteno wrote:HHasKey( aHash, "O-2222-BB" ) --> lExists
Y esta 32,91 segundos.
MarioG wrote:if "M-9999-DF" IN aHash

Re: Iniciandome en el manejo de tablas HASH

Posted: Tue Mar 13, 2012 9:35 pm
by MarioG
JmGarcia wrote:Para 10 millones de iteraciones es mas rápida la sentencia "IN" que la función "HHasKey"

Esta tarda 34,84 seg.
jcenteno wrote:HHasKey( aHash, "O-2222-BB" ) --> lExists
Y esta 32,91 segundos.
MarioG wrote:if "M-9999-DF" IN aHash
muy buen aporte

Re: Iniciandome en el manejo de tablas HASH

Posted: Tue Mar 13, 2012 9:40 pm
by JmGarcia
MarioG wrote:mas arriba, en el post que te escribí está
Perdona pero no "lo veo" :roll:



He de decir que el contenido de cada elemento de la tabla ha de ser un OBJETO de una clase.
MarioG wrote:

Code: Select all

? "No existe"
aHash["M-9999-DF"]:= "M-9999-DF"
Al no existir el elemnto lo daría de alta asi:

Code: Select all

? "No existe"
aHash[ "M-1234-DF" ] := Tcoche():New( "M-1234-DF" )

Re: Iniciandome en el manejo de tablas HASH

Posted: Tue Mar 13, 2012 9:51 pm
by MarioG

Code: Select all

HEval( aHash, {|cKey,cVal| wqout({cKey,cVal}) })
Supongo que en este caso será: cKey = "M-9999-DF" y cVal = "O" (Object)

Re: Iniciandome en el manejo de tablas HASH

Posted: Tue Mar 13, 2012 10:09 pm
by JmGarcia
He encontrado una forma de recorrer la tabla:

Code: Select all

for nIndice=1 to len(aHash)
   cMatricula:=HGetKeyAt(aHash,nIndice)
   ? aHash[cMatricula]:cMatricula
   ? aHash[cMatricula]:cMarca
   ? aHash[cMatricula]:nPrecio
   ? aHash[cMatricula]:cColor
next nIndice