On Sat, 07 Nov 2009, Fernando Athayde wrote:
Hi,
> ASORT(::aArrayResumo, {|a,b| str(a[1],11)+str(a[3],11)+dtoc(a[5])+a[7] >
> str(b[1],11)+str(b[3],11)+dtoc(b[5])+b[7] } )
> //Normal way (Slow for more than 100 registers)
> nPosicaoArray := ASCAN(::aArrayResumo, ;
> {|a| str(a[1],11)+str(a[3],11)+dtoc(a[5])+a[7] ==;
> STR(
> ::oQueryRelatorioPrincipal:fieldGet('idgrupo_centro_custo'),11)+;
>
> STR(::oQueryRelatorioPrincipal:fieldGet('idcentro_custo'),11 )+;
> DTOC(oDB:Mysql2Date
> (::oQueryRelatorioPrincipal:fieldGet('data_emissao') ) )+cSiglaMoeda} )
>
> //Weighted search (Is very fast)
> nPosicaoArray := 0
> nArraySize := LEN( ::aArrayResumo )
> nJump := nArraySize - 1
> nPosition := 1
> DO WHILE .T.
> nPosition += nJump
> IF nPosition > nArraySize
> nJump := 0
> nPosition := nArraySize
> ENDIF
> IF str(::aArrayResumo[nPosition,1],11)+str(::aArrayResumo[nPosition,3],11);
> +dtoc(::aArrayResumo[nPosition,5])+::aArrayResumo[nPosition,7]
> >;
> STR( ::oQueryRelatorioPrincipal:fieldGet('idgrupo_centro_custo'),11 );
> +STR(
> ::oQueryRelatorioPrincipal:fieldGet('idcentro_custo'),11 );
> +DTOC(oDB:Mysql2Date
> (::oQueryRelatorioPrincipal:fieldGet('data_emissao') ) )+cSiglaMoeda
>
> nPosition -= nJump
> nJump := INT(nJump/2)
> ENDIF
> IF str(::aArrayResumo[nPosition,1],11)+str(::aArrayResumo[nPosition,3],11);
> +dtoc(::aArrayResumo[nPosition,5])+::aArrayResumo[nPosition,7] ==
> STR( ::oQueryRelatorioPrincipal:fieldGet('idgrupo_centro_custo'),11 );
> +STR( ::oQueryRelatorioPrincipal:fieldGet('idcentro_custo'),11 );
> +DTOC(oDB:Mysql2Date
> (::oQueryRelatorioPrincipal:fieldGet('data_emissao') ) )+cSiglaMoeda
> nPosicaoArray := nPosition
> EXIT
> ENDIF
> IF nJump<1
> EXIT
> ENDIF
> ENDDO
>
> my proposal is made a ASCANEX sending a block how parameter
> but i don´t know how to use eval and blocks
You want to use binary search for well soprted array items and
for sure it will improve the speed anyhow I suggest to use hash
arrays. If will be faster.
You can use hash array in two ways:
1. as index, i.e.:
func arrayIndex( aValue, bOrder )
local item
local hValue := {=>}
for each item in aValue
hValue[ eval( bOrder, item ) ] := item:__enumIndex()
next
return hValue
then in your code you are making:
hIndex := arrayIndex( ::aArrayResumo, ;
{ |a| str(a[1],11)+str(a[3],11)+dtoc(a[5])+a[7] } )
and you can use this index to find given value position:
cKey := STR(
::oQueryRelatorioPrincipal:fieldGet('idgrupo_centro_custo'),11)+;
STR(::oQueryRelatorioPrincipal:fieldGet('idcentro_custo'),11 )+;
DTOC(oDB:Mysql2Date(::oQueryRelatorioPrincipal:fieldGet('data_emissao') ) )+;
cSiglaMoeda
if cKey $ hIndex
nPosicaoArray := hIndex[ cKey ]
aResult := ::aArrayResumo[ nPosicaoArray ]
endif
2. as array of values.
func arrayToHash( aValue, bOrder )
local item
local hValue := {=>}
for each item in aValue
hValue[ eval( bOrder, item ) ] := item
next
return hValue
then in your code you are making:
hValue := arrayToHash( ::aArrayResumo, ;
{ |a| str(a[1],11)+str(a[3],11)+dtoc(a[5])+a[7] } )
and you can use this index to find given value:
cKey := STR(
::oQueryRelatorioPrincipal:fieldGet('idgrupo_centro_custo'),11)+;
STR(::oQueryRelatorioPrincipal:fieldGet('idcentro_custo'),11 )+;
DTOC(oDB:Mysql2Date(::oQueryRelatorioPrincipal:fieldGet('data_emissao') ) )+;
cSiglaMoeda
if cKey $ hValue
aResult := hValue[ cKey ]
endif
Now if you look at the above the you will find that you do not have to use
arrays at all and you can replace ::aArrayResumo with ::hArrayResumo.
Just simply initialize it as empty hash array:
::hArrayResumo := { => }
then add all new values using code like:
cKey := str(a[1],11)+str(a[3],11)+dtoc(a[5])+a[7]
::hArrayResumo[ cKey ] := a
instead of:
aadd( ::aArrayResumo, a )
and now you can use ::hArrayResumo directly, i.e.:
cKey := STR(
::oQueryRelatorioPrincipal:fieldGet('idgrupo_centro_custo'),11)+;
STR(::oQueryRelatorioPrincipal:fieldGet('idcentro_custo'),11 )+;
DTOC(oDB:Mysql2Date(::oQueryRelatorioPrincipal:fieldGet('data_emissao') ) )+;
cSiglaMoeda
if cKey $ ::hArrayResumo
aResult := ::hArrayResumo[ cKey ]
endif
Hash array are designed to replace normal arrays accessed by indexes
extracted with ascan() functions and are extremely fast.
best regards,
Przemek
_______________________________________________
Harbour mailing list
[email protected]
http://lists.harbour-project.org/mailman/listinfo/harbour