hash with (x)harbour - knowledge base

Frank Demont
Posts: 142
Joined: Sun Oct 09, 2005 10:59 am

Re: hash with (x)harbour - knowledge base

Post by Frank Demont »

A Good example from using hashes is when tabels or dbf's must be totalisized.
See code

Code: Select all

//# define NOHASH
FUNCTION MAIN
LOCAL aTabel := {{"CL1",10},{"CL1",20},{"CL1",30},{"CL1",40},{"CL2",10},{"CL2",20}}
LOCAL el , i , ClNr
# ifdef NOHASH
LOCAL aSum[0]
FOR EACH el IN aTabel
    ClNr := el[1]
    i := ASCAN(aSum , {|x|x[1]==ClNr})
    IF i == 0
        AADD(aSum,{ClNr,0})
        i := LEN(aSum)
    END
    aSum[i,2] += el[2]
NEXT
FOR EACH el IN aSum
    ? el[1] , el[2]
NEXT
# else
LOCAL hSum := Hash()
FOR EACH el IN aTabel
    ClNr := el[1]
    IF ! (ClNr IN hSum)
        hSum[ClNr] := 0
    END
    hSum[ClNr] += el[2]
NEXT
FOR EACH el In hGetKeys(hSum)
    ? el , hSum[el]
NEXT
# endif
WAIT
RETURN nil
 
User avatar
reinaldocrespo
Posts: 918
Joined: Thu Nov 17, 2005 5:49 pm
Location: Fort Lauderdale, FL

Re: hash with (x)harbour - knowledge base

Post by reinaldocrespo »

Hi all;

I use hashes a lot. Never had a problem.

The sample Maurizzio shows is a good one. In essence, with his scatter you can refer to an array entry using syntax like : ?aVar[ LASTNAME ] to show what's in the buffer for oCust:LASTNAME. Clearly using the aforementioned syntax is much better than ?aVar[ 32 ] or even ?aVar[ _LASTNAME ] where _LASTNAME is #defined as 32. And if you keep a hash as one of the properties (DATA) of your tdata class, you could refer to the buffer field as: oCust:aVar[ LASTNAME ] or even oCust:aVarLastName...

Here is a simpler use of hashes I use a lot to show descriptive information on a combobox:

Code: Select all

local hRels     := { " " =>" ", "Self"=>"S ", "Spouse"=>"01", "Child"=>"19", "Other"=>"G8", ;
                    "Organ Donor" => "39", "Cadaver Donor" => "40", "Life Partner" => "53" } 

...


    ret := aScan( hGetKeys( hRels ), { |e| hRels[ e ] == odbf:aVar[Relation] } )

    crel1 := hGetKeyAt( hRels, max( ret, 1 ) )

    REDEFINE COMBOBOX agets[ 21 ] VAR crel1 ID 130 OF oDlg Items hGetKeys( hRels ) ;
        Valid( odbf:aVar[Relation] := hRels[ crel1 ], .t. )

 
Here the dropdown list shows "Self", "Spouse", "Child", "Other"... but what's save to file is the code "01", "19", "G8"... In this case saving codes instead of description is important in order to comply with EDI rules.

I Hope that makes sense.


Reinaldo.
hua
Posts: 861
Joined: Fri Oct 28, 2005 2:27 am

Re: hash with (x)harbour - knowledge base

Post by hua »

How to create a 2-dimensional associative array? For example let's consider something similar to a spreadsheet where the columns are A to E, the rows are 1 to 6 [equivalent to array(5,6) matrix]

The few questions that I have are:
i. How to initialize it? [I mean its array(5,6) equivalent]

ii. Would this be the correct way to create and initialize the hash table and its values?

Code: Select all

oTable := hash()
oTable["A"]["1"] := 0
oTable["B"]["1"] := 0
oTable["C"]["1"] := 0
oTable["D"]["1"] := 0
oTable["E"]["1"] := 0
oTable["A"]["2"] := 0
   .
   .
oTable["A"]["6"] := 0
oTable["B"]["6"] := 0
oTable["C"]["6"] := 0
oTable["D"]["6"] := 0
oTable["E"]["6"] := 0
iii. Does an associative array has something similar to asort()?

That's all for now. TIA
FWH 11.08/FWH 19.03
xHarbour 1.2.1 (Rev 6406) + BCC
Harbour 3.1 (Rev 17062) + BCC
Harbour 3.2.0dev (r1904111533) + BCC
Demont Brecht
Posts: 55
Joined: Fri Jul 08, 2011 6:43 am

Re: hash with (x)harbour - knowledge base

Post by Demont Brecht »

hua wrote:How to create a 2-dimensional associative array? For example let's consider something similar to a spreadsheet where the columns are A to E, the rows are 1 to 6 [equivalent to array(5,6) matrix]

The few questions that I have are:
i. How to initialize it? [I mean its array(5,6) equivalent]

ii. Would this be the correct way to create and initialize the hash table and its values?

Code: Select all

oTable := hash()
oTable["A"]["1"] := 0
oTable["B"]["1"] := 0
oTable["C"]["1"] := 0
oTable["D"]["1"] := 0
oTable["E"]["1"] := 0
oTable["A"]["2"] := 0
   .
   .
oTable["A"]["6"] := 0
oTable["B"]["6"] := 0
oTable["C"]["6"] := 0
oTable["D"]["6"] := 0
oTable["E"]["6"] := 0
iii. Does an associative array has something similar to asort()?

That's all for now. TIA
It Could be done as :

oTabel := Hash()
HsetAAcompability(oTable , .T.)
FOR i := 1 TO 6
//oTabel["A"] := Hash()
oTabel[CHR(64+i)] := Hash()
HsetAAcompability(oTabel[CHR(64+i)],.T.)
FOR j := 1 TO 6
c := LTRIM(STR(j))
oTabel[CHR(64+i),c] := 0
NEXT
NEXT

Elements can be retrieved as oTabel["A","1"] or as oTabel[1,1] or both mixed

A better aproach would be :
oTabel := Hash()
FOR i := 1 TO 6
oTabel[CHR(64+i)] := Array(6)
aFill(oTabel[CHR(64+i)],0)
//FOR j := 1 TO 6
// oTabel[CHR(64+i),j] := 0
//NEXT
NEXT

Elements can only be retrieved as oTabel["A",1]


Note that a hash() has only the properties from a associative array when is used
HsetAAcompability(<hHash>,<lToggle>) . In that case the creation order is respected and the elements can be retrieved with their numeric ordinal position (i.e. oTabel[1,"1"])


A hash is ordered on the key (in this example it makes no difference) , it can only be retrieved with the key (i.e. oTabel["A",1])



Frank
hua
Posts: 861
Joined: Fri Oct 28, 2005 2:27 am

Re: hash with (x)harbour - knowledge base

Post by hua »

Thank you for clearing up the picture a bit more Frank :)
FWH 11.08/FWH 19.03
xHarbour 1.2.1 (Rev 6406) + BCC
Harbour 3.1 (Rev 17062) + BCC
Harbour 3.2.0dev (r1904111533) + BCC
User avatar
Otto
Posts: 4470
Joined: Fri Oct 07, 2005 7:07 pm
Contact:

Re: hash with (x)harbour - knowledge base

Post by Otto »

Does xHarbour support hash functions?

Both Harbour and xHarbour support all these functions but with slightly different names.
hbcompat.ch provides cross translations.

Code: Select all

  #ifdef __XHARBOUR__
       /* Hash item functions */
       #xtranslate hb_Hash( [<x,...>] )            => Hash( <x> )
       #xtranslate hb_HHasKey( [<x,...>] )         => HHasKey( <x> )
       #xtranslate hb_HPos( [<x,...>] )            => HGetPos( <x> )
       #xtranslate hb_HGet( [<x,...>] )            => HGet( <x> )
       #xtranslate hb_HSet( [<x,...>] )            => HSet( <x> )
       #xtranslate hb_HDel( [<x,...>] )            => HDel( <x> )
       #xtranslate hb_HKeyAt( [<x,...>] )          => HGetKeyAt( <x> )
       #xtranslate hb_HValueAt( [<x,...>] )        => HGetValueAt( <x> )
       #xtranslate hb_HValueAt( [<x,...>] )        => HSetValueAt( <x> )
       #xtranslate hb_HPairAt( [<x,...>] )         => HGetPairAt( <x> )
       #xtranslate hb_HDelAt( [<x,...>] )          => HDelAt( <x> )
       #xtranslate hb_HKeys( [<x,...>] )           => HGetKeys( <x> )
       #xtranslate hb_HValues( [<x,...>] )         => HGetValues( <x> )
       #xtranslate hb_HFill( [<x,...>] )           => HFill( <x> )
       #xtranslate hb_HClone( [<x,...>] )          => HClone( <x> )
       #xtranslate hb_HCopy( [<x,...>] )           => HCopy( <x> )
       #xtranslate hb_HMerge( [<x,...>] )          => HMerge( <x> )
       #xtranslate hb_HEval( [<x,...>] )           => HEval( <x> )
       #xtranslate hb_HScan( [<x,...>] )           => HScan( <x> )
       #xtranslate hb_HSetCaseMatch( [<x,...>] )   => HSetCaseMatch( <x> )
       #xtranslate hb_HCaseMatch( [<x,...>] )      => HGetCaseMatch( <x> )
       #xtranslate hb_HSetAutoAdd( [<x,...>] )     => HSetAutoAdd( <x> )
       #xtranslate hb_HAutoAdd( [<x,...>] )        => HGetAutoAdd( <x> )
       #xtranslate hb_HAllocate( [<x,...>] )       => HAllocate( <x> )
       #xtranslate hb_HDefault( [<x,...>] )        => HDefault( <x> )
    #else
       /* Hash item functions */
       #xtranslate Hash( [<x,...>] )           => hb_Hash( <x> )
       #xtranslate HHasKey( [<x,...>] )        => hb_HHasKey( <x> )
       #xtranslate HGetPos( [<x,...>] )        => hb_HPos( <x> )
       #xtranslate HGet( [<x,...>] )           => hb_HGet( <x> )
       #xtranslate HSet( [<x,...>] )           => hb_HSet( <x> )
       #xtranslate HDel( [<x,...>] )           => hb_HDel( <x> )
       #xtranslate HGetKeyAt( [<x,...>] )      => hb_HKeyAt( <x> )
       #xtranslate HGetValueAt( [<x,...>] )    => hb_HValueAt( <x> )
       #xtranslate HSetValueAt( [<x,...>] )    => hb_HValueAt( <x> )
       #xtranslate HGetPairAt( [<x,...>] )     => hb_HPairAt( <x> )
       #xtranslate HDelAt( [<x,...>] )         => hb_HDelAt( <x> )
       #xtranslate HGetKeys( [<x,...>] )       => hb_HKeys( <x> )
       #xtranslate HGetValues( [<x,...>] )     => hb_HValues( <x> )
       #xtranslate HFill( [<x,...>] )          => hb_HFill( <x> )
       #xtranslate HClone( [<x,...>] )         => hb_HClone( <x> )
       #xtranslate HCopy( [<x,...>] )          => hb_HCopy( <x> )
       #xtranslate HMerge( [<x,...>] )         => hb_HMerge( <x> )
       #xtranslate HEval( [<x,...>] )          => hb_HEval( <x> )
       #xtranslate HScan( [<x,...>] )          => hb_HScan( <x> )
       #xtranslate HSetCaseMatch( [<x,...>] )  => hb_HSetCaseMatch( <x> )
       #xtranslate HGetCaseMatch( [<x,...>] )  => hb_HCaseMatch( <x> )
       #xtranslate HSetAutoAdd( [<x,...>] )    => hb_HSetAutoAdd( <x> )
       #xtranslate HGetAutoAdd( [<x,...>] )    => hb_HAutoAdd( <x> )
       #xtranslate HAllocate( [<x,...>] )      => hb_HAllocate( <x> )
       #xtranslate HDefault( [<x,...>] )       => hb_HDefault( <x> )
       #xtranslate HSetPartition( [<x,...>] )  =>

       /* Associative hash array functions */
       #xtranslate haAGetKeyAt( [<x,...>] )    => hb_HKeyAt( <x> )
       #xtranslate haAGetValueAt( [<x,...>] )  => hb_HValueAt( <x> )
       #xtranslate haADelAt( [<x,...>] )       => hb_HDelAt( <x> )
       #xtranslate haAGetPos( [<x,...>] )      => hb_HPos( <x> )
       #xtranslate haAGetRealPos( <x>, <y> )   => iif( HB_ISNUMERIC( <y> ) .AND. <y> >= 1 .AND. ;
                                                       Int( <y> ) <= Len( <x> ), Int( <y> ), 0 )
       #xtranslate HGetVaaPos( <x> )           => {| h | ;;
                                                    LOCAL a := Array( Len( h ), v ;;
                                                    FOR EACH v IN a ;;
                                                       v := v:__enumIndex() ;;
                                                    NEXT ;;
                                                    RETURN a ; }:eval( <x> )
       #xtranslate HGetAACompatibility( <x> )  => hb_HKeepOrder( <x> )
       #xtranslate HSetAACompatibility( [<x,...>] ) => {| h | ;;
                                                       hb_HKeepOrder( h ) ;;
                                                       RETURN .T. ; }:eval( <x> )

    #endif
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org

********************************************************************
Post Reply