Some details of hash manipulations:
HB_HCOPY() function copies a hash to another.
Syntax :
HB_HCOPY( <hsDestination>, <hsSource>, [<nStart>], [<nCount>] ) ->
<hsDestination>
As noticed in syntax, copy operation may be limited by [<nStart>], [<nCount>] arguments.
But a hash may NOT built by “COPY” method; because <hsDestination> argument isn’t optional.
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hFruits2 := HB_HCOPY( hFruits ) // Argument error !
Though it’s possible in two steps:
hFruits2 := HB_HASH() // Built first an empty hash
hFruits2 := HB_HCOPY(hFruits2, hFruits ) // copy second onto first
As a result, for hash copy process two hashes should be exist:
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hDays := { "days" => { "sunday", "monday" } }
hFruits := HB_HCOPY( hFruits, hDays )
or
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hDays := { "days" => { "sunday", "monday" } }
hTarget := HB_HASH()
hTarget := HB_HCOPY( hTarget, hFruits )
hTarget := HB_HCOPY( hTarget, hDays )
HB_HMERGE() function merge two hashes.
Syntax:
HB_HMERGE( <hsDestination>, <hsSource>, <bBlock>|<nPosition> ) ->
<hsDestination>
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hDays := { "days" => { "sunday", "monday" } }
hMerged := HB_HMERGE( hFruits, hDays )
hFruits :
1 days => sunday monday
2 fruits => apple cherry apricot
hTarget :
1 days => sunday monday
2 fruits => apple cherry apricot
AADD( hFruits[ "fruits" ], "melon" )
hFruits and hTarget :
1 days => sunday monday
2 fruits => apple cherry apricot melon
Result of above tests :
HB_HCOPY() and HB_HMERGE() doesn’t “physically” copy / merge hashes data; instead, copy / merge only by reference(s).
HB_HCLONE() function : Cloning (exact copy of) hashes.
Syntax:
HB_HCLONE( <hsTable> ) -> <hsDestination>
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hClone := HB_HCLONE( hFruits )
hClone : fruits => apple cherry apricot
AADD( hFruits[ "fruits" ], "melon" ) // Source changed
hClone : fruits => apple cherry apricot
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._./*
Hash Details - 1
Copy, Merge & Clone Hashes.
*/
#define NTrim( x ) IF( HB_ISNUMERIC( x ), LTRIM( STR( x ) ), x )
PROCEDURE Main()
SET COLO TO "W/B"
cLMarj := SPACE( 3 )
CLS
? "Copy one hash to another : HB_HCOPY() function : "
? "Syntax :",;
"HB_HCOPY( <hsDestination>, <hsSource>, [<nStart>],"
? " [<nCount>] ) -> <hsDestination>"
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hDays := { "days" => { "sunday", "monday" } }
* hFruits2 := HB_HCOPY( hFruits ) // Argument error !
hFruits := HB_HCOPY( hFruits, hDays )
ListHash( hFruits, "Copied-1 (Fruits)" )
hDays[ "days" ] := "friday"
ListHash( hFruits, "copied or referenced ?" )
hTarget := HB_HASH()
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hDays := { "days" => { "sunday", "monday" } }
hTarget := HB_HCOPY( hTarget, hFruits )
hTarget := HB_HCOPY( hTarget, hDays )
ListHash( hTarget, "Copied-2 ( Target )" )
AADD( hFruits[ "fruits" ], "melon" )
ListHash( hTarget, "copied or referenced ?" )
? "Merge two hashes : HB_HMERGE() function : "
? "Syntax :",;
"HB_HMERGE( <hsDestination>, <hsSource>, <bBlock>|"
? " <nPosition> ) -> <hsDestination>"
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hDays := { "days" => { "sunday", "monday" } }
hMerged := HB_HMERGE( hFruits, hDays )
ListHash( hFruits, "Merged (hFruits)" )
ListHash( hMerged, "Merged (hTarget)" )
AADD( hFruits[ "fruits" ], "melon" )
ListHash( hFruits, "Merged or referenced ? ( hFruits) " )
ListHash( hMerged, "Merged or referenced ? ( hMerged) " )
*
* Result of above tests :
*
* HB_HCOPY() and HB_HMERGE() doesn't "physically" copy / merge hashes data;
*
* instead copy / merge only by reference(s).
*
? "Cloning (exact copy of) hashes : HB_HCLONE() function : "
? "Syntax :",;
"HB_HCLONE( <hsTable> ) -> <hsDestination>"
hFruits := { "fruits" => { "apple", "cherry", "apricot" } }
hClone := HB_HCLONE( hFruits )
ListHash( hClone, "Cloned" )
AADD( hFruits[ "fruits" ], "melon" )
ListHash( hClone, "Source changed" )
?
@ MAXROW(), 0
WAIT "EOF HashDetails-1.prg"
RETURN // HashDetails-1.Main()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.
PROCEDURE ListHash( hHash, cComment )
LOCAL x1Pair := NIL
cComment := IF( HB_ISNIL( cComment ), '', cComment )
? cComment, ''
* ?? "-- Type :", VALTYPE( hHash ),''
* ?? "size:", NTrim ( LEN( hHash ) )
?
FOR EACH x1Pair IN hHash
nIndex := x1Pair:__ENUMINDEX()
x1Key := x1Pair:__ENUMKEY()
x1Value := x1Pair:__ENUMVALUE()
? cLMarj, NTrim( nIndex )
* ?? '', VALTYPE( x1Pair )
?? '', NTrim( x1Key ), "=>"
* ?? '', VALTYPE( x1Key )
* ?? VALTYPE( x1Value )
IF HB_ISARRAY( x1Value )
AEVAL( x1Value, { | x1 | QQOUT( '', x1 ) } )
ELSE
?? '', NTrim( x1Value )
ENDIF
NEXT
? REPL( "~", 32 )
RETURN // ListHash()
*-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.-._.
