Re: MivaScript.com is now LIVE!
Hi Ray,
Thanks for your message and your kind words. You inspired me to finally write my sorting function correctly, and sorry for the mistakes in my quick reply earlier.
Here is a tested function to sort arrays of structures by element, that works for numbers (positive and negative sorted correctly, keeping duplicates) and words/letters and numbers. You can choose to get the result in ascending or descending order (l.direction either 'desc' or 'asc'/leaving it blank).
The beauty of this little function is that it preserves the structure of the array, so it returns an identical structure with all elements only in the new order of the selected element.
For obvious reasons, it is not as fast as the other sorting algorithms (it can be easily made faster by simplifying it a bit) , but in many cases quite useful. Enjoy!
You can see the script in action here:
http://www.sylter-seiten.de/Balance/....mvc?max=10000
It performs two sorting operations, one by number, one by letters. With the parameter max you can try different sizes of the array, however I limited the script to 12000.
Note: The drawback of this method is that it only works fast up to approx. 11500 members. After that, Miva really gets problems with the arrays and slows terribly down. For bigger arrays, I'd use a different sorting algorithm which is however much more complicated to write.
Markus
here it comes:
Hi Ray,
Thanks for your message and your kind words. You inspired me to finally write my sorting function correctly, and sorry for the mistakes in my quick reply earlier.
Here is a tested function to sort arrays of structures by element, that works for numbers (positive and negative sorted correctly, keeping duplicates) and words/letters and numbers. You can choose to get the result in ascending or descending order (l.direction either 'desc' or 'asc'/leaving it blank).
The beauty of this little function is that it preserves the structure of the array, so it returns an identical structure with all elements only in the new order of the selected element.
For obvious reasons, it is not as fast as the other sorting algorithms (it can be easily made faster by simplifying it a bit) , but in many cases quite useful. Enjoy!
You can see the script in action here:
http://www.sylter-seiten.de/Balance/....mvc?max=10000
It performs two sorting operations, one by number, one by letters. With the parameter max you can try different sizes of the array, however I limited the script to 12000.
Note: The drawback of this method is that it only works fast up to approx. 11500 members. After that, Miva really gets problems with the arrays and slows terribly down. For bigger arrays, I'd use a different sorting algorithm which is however much more complicated to write.
Markus
here it comes:
Code:
<MvCOMMENT>This first part is just to build a random structure (l.array[x]:price and l.array[x]:code) of l.max elements</MvCOMMENT> <MvASSIGN NAME = "l.al" VALUE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_.;" > <MvASSIGN NAME = "l.max" VALUE = "1000" > <MvASSIGN NAME = "l.a" VALUE = "1" > <MvWHILE EXPR = "{ l.a LE l.max }"> <MvIF EXPR = "{ NOT fmod(l.a,2) }" > <MvASSIGN NAME = "l.array" INDEX="{l.a}" MEMBER="Price" VALUE = "{(random(10000)$'.'$random(100))*(-1) }" > <MvELSE> <MvASSIGN NAME = "l.array" INDEX="{l.a}" MEMBER="Price" VALUE = "{(random(10000)$'.'$random(100))*1 }" > </MvIF> <MvASSIGN NAME = "l.array" INDEX="{l.a}" MEMBER="CODE" VALUE = "{substring(l.al,random(36),1)$substring(l.al,random(36),1)$substring(l.al,random(36),1)$substring(l.al,random(36),1)$substring(l.al,random(36),1)$substring(l.al,random(36),1) }" > <MvASSIGN NAME = "l.a" VALUE = "{ l.a+1 }" > </MvWHILE> <BR>************************************* <BR>Sort array by price, descending <MvASSIGN NAME = "l.new" VALUE = "{ sort_array_by_element( l.array,'price','desc')}" > <MvASSIGN NAME = "l.a" VALUE = "1" > <MvWHILE EXPR = "{ l.new[l.a]:price }"> <BR><MvEVAL EXPR = "{ l.a }" >.- <MvEVAL EXPR = "{ l.new[l.a]:CODE}" > ...... <MvEVAL EXPR = "{ l.new[l.a]:PRICE}" > <MvASSIGN NAME = "l.a" VALUE = "{ l.a+1 }" > </MvWHILE> <BR>///////////////////////////////////////// <BR>Sort array by code, default order (asc) <MvASSIGN NAME = "l.new" VALUE = "{ sort_array_by_element( l.array,'code','')}" > <MvASSIGN NAME = "l.a" VALUE = "1" > <MvWHILE EXPR = "{ l.new[l.a]:code }"> <BR><MvEVAL EXPR = "{ l.a }" >.- <MvEVAL EXPR = "{ l.new[l.a]:CODE}" > ...... <MvEVAL EXPR = "{ l.new[l.a]:PRICE}" > <MvASSIGN NAME = "l.a" VALUE = "{ l.a+1 }" > </MvWHILE> <MvEXIT> Here comes the actual function: <MvFUNCTION NAME = "sort_array_by_element" PARAMETERS="array VAR,element,direction" STANDARDOUTPUTLEVEL = "html,text,compresswhitespace"> <MvASSIGN NAME = "l.max" VALUE = "{ miva_array_max( l.array ) }"> <MvASSIGN NAME = "l.pos" VALUE = "{ 1 }"> <MvWHILE EXPR = "{ l.pos LE l.max }"> <MvIF EXPR = "{ miva_variable_value( 'l.array[' $ l.pos $ ']:' $ l.element ) }"> <MvIF EXPR = "{ miva_variable_value( 'l.array[' $ l.pos $ ']:' $ l.element ) LT 1}" > <MvCOMMENT>handling negative numbers </MvCOMMENT> <MvASSIGN NAME = "l.v" VALUE = "{ 10000000000000+miva_variable_value( 'l.array[' $ l.pos $ ']:' $ l.element )}" > <MvASSIGN NAME = "l.str" VALUE = "{ ' '$ padl(gettoken(l.v,'.',1),15,'0')$'.'$ padr(gettoken( l.v,'.',2),8,'0')}" > <MvELSEIF EXPR = "{ miva_variable_value( 'l.array[' $ l.pos $ ']:' $ l.element ) GT 0 }" > <MvCOMMENT>handling positive numbers </MvCOMMENT> <MvASSIGN NAME = "l.str" VALUE = "{ padl(gettoken( miva_variable_value( 'l.array[' $ l.pos $ ']:' $ l.element ),'.',1),15,'0')$'.'$ padr(gettoken( miva_variable_value( 'l.array[' $ l.pos $ ']:' $ l.element ),'.',2),8,'0')}" > <MvELSE> <MvCOMMENT>handling letters and numbers (case insensitive)</MvCOMMENT> <MvASSIGN NAME = "l.str" VALUE = "{ padl(substring( miva_variable_value( 'l.array[' $ l.pos $ ']:' $ l.element ),1,21),21,'0')}" > </MvIF> <MvCOMMENT>build a new sorted index</MvCOMMENT> <MvASSIGN NAME = "{ 'l.index:'$l.str }" INDEX="{ miva_array_max(miva_variable_value( 'l.index:'$l.str) )+1 }" VALUE = "{ l.pos }" > </MvIF> <MvASSIGN NAME = "l.pos" VALUE = "{ l.pos+1 }"> </MvWHILE> <MvASSIGN NAME = "l.index" VALUE = "{ miva_array_deserialize(trim(l.index)) }" > <MvIF EXPR = "{ l.direction AND NOT ('a' CIN l.direction)}" > <MvCOMMENT><BR><B>DESCENDING</B></MvCOMMENT> <MvASSIGN NAME = "l.a" VALUE = "{ miva_array_max(l.index) }" > <MvWHILE EXPR = "{ l.a GE 1 }"> <MvASSIGN NAME = "l.b" VALUE = "{ l.b+1 }" > <MvASSIGN NAME = "l.new" INDEX="{l.b}" VALUE = "{ l.array[l.index[l.a]] }" > <MvASSIGN NAME = "l.a" VALUE = "{ l.a-1 }" > </MvWHILE> <MvELSE> <MvASSIGN NAME = "l.a" VALUE = "1" > <MvWHILE EXPR = "{ l.a LE miva_array_max(l.index) }"> <MvASSIGN NAME = "l.new" INDEX="{l.a}" VALUE = "{ l.array[l.index[l.a]] }" > <MvASSIGN NAME = "l.a" VALUE = "{ l.a+1 }" > </MvWHILE> </MvIF> <MvFUNCRETURN VALUE="{ l.new }"> </MvFUNCTION>
Comment