THIS CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED;
THE AUTHOR DISCLAIMS ALL LIABILITY FOR ANY DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR STORE DISRUPTIONS ARISING FROM ITS USE.
NOTE: As of Aug 2026 you probably don't need to create a reference array. I've been able to make array values stick just by running through and adding, removing, updating vars in the structure during the loop.
Note 2: Sorting data must NOT begin with numbers.
Note 3: This only sorts top level arrays. If you have a structure with another array, such as l.settings:order:items inside l.settings:admin_orders in a batch report you must copy the items array (for example) to a temporary array, sort that, and then clear the items array in the original structure and then copy the newly sorted array back.
QuickSortArray can be used to sort by any top level field in the structure.
Cool trick: What if the sort field doesn't exist? That is, what is you want to sort by say, the date and the last name of the customer from an array of orders? Roll through the array and create a sort field on the fly. Simple example. Notice we are starting the sort with a random letter, in this case the letter "a" because the quicksortarray function doesn't seem to work well if the sorting string begins with a number.
<mvt:foreach iterator="order" array="orders">
<mvt:assign name="l.settings:order:sort" value="'a' $ l.settings:order:id $ l.settings:order:bill_lname" />
</mvt:foreach>
<mvt:do file="g.Module_Library_Utilities" name="l.success" value="QuickSortArray(l.settings:orders), ':sort', 'asc')" />
Note that you can make your own sort routines using the quicksortarray function and your own callbacks. Miva docs: https://www.mivascript.com/topic/sort-algorithms.html
Sort using Reference Array
Scenario: Sort shipping methods from low to high while including the name so that shipping fees are grouped from via provider from low to high, such as UPS, USPS, FED EX, etc...
Note: We'll be using the miva_array_copy_ref(...) method so we don't need to create a second array (unnecessary at this point but useful for other things so we'll leave it here.)
Create a new field in the shipping methods array specifically for sorting, set up a temporary array, then move data to original array.
<mvt:assign name="l.ok" value="miva_array_copy_ref(l.settings:shippingmethods,1,miva_array_elements(l.settings:shipping_methods),l.settings:smethods,1)" />
<mvt:foreach iterator="method" array="smethods">
<mvt:assign name="l.settings:method:sort" value="l.settings:method:name $ l.settings:method:price" />
</mvt:foreach>
<mvt:do file="g.Module_Library_Utilities" name="l.success" value="QuickSortArray(l.settings:shippingmethods, ':sort', 'asc')" />
Now when you roll through the array, the methods are sorted by the :sort field.