4D offers powerful features to work with object collections. For example, you can create a collection of cities with their associated countries and continents. Manipulating these collections with built-in functions like sort, order, and filter becomes a breeze.
4D v20 R3 introduces the new multiSort() function to simplify this process. With this function, you can now easily sort and synchronize multiple collections.
New function
This new multiSort() function lets you carry out a multi-level synchronized sort on a set of collections.
If the function is called with no parameters, the function has the same effect as the .sort() function. The collection is sorted (only scalar values) in ascending order by default, according to their type.
If you want to sort the collections in some other order than ascending, you must supply a formula.
$col.multiSort( [ $col2 ; $col3 ] )
$col.multiSort( $formula; [$col2 ; $col3] )
It is also possible to define a multi-level synchronized sort. This is similar to the SORT MULTIPLE ARRAY command.
In this case, you need to pass an object containing collection and order attributes.
$col.multiSort( [ {collection: $col2; order: ck ascending} ; $col3 ] )
$col.multiSort( [ $formula; {collection: $col2; order: ck ascending} ; $col3 ] )
Moreover, the sorting algorithm is said to be stable, i.e., two elements with the same value appear in the same order in the sorted output as in the input data set.
Examples
Let’s go back to our example of city, country, and continent:
var $city : Collection
var $country : Collection
var $continent : Collection
$city:=["Paris"; "Lyon"; "Rabat"; "Eching"; "San Diego"]
$country:=["France"; "France"; "Morocco"; "Germany"; "US"]
$continent:=["Europe"; "Europe"; "Africa"; "Europe"; "America"]
Example 1: A simple sort of the first collection ($continent) with synchronization of the other collections ($country and $city)
$continent.multiSort([$country; $city])
The result is:
"Africa"; "America"; "Europe"; "Europe"; "Europe" "Morocco"; "US"; "France"; "France"; "Germany" "Rabat"; "San Diego"; "Paris"; "Lyon"; "Eching"
Example 2: Ascending sort of the first and the third collections ($continent and $city), and synchronization for the second collection ($country)
$continent.multiSort([$country; {collection: $city; order: ck ascending}])
The result is:
"Africa"; "America"; "Europe"; "Europe"; "Europe" "Morocco"; "US"; "Germany"; "France"; "France" "Rabat"; "San Diego"; "Eching"; "Lyon"; "Paris"
Example 3: Formula sort of the first collection ($continent) and synchronization for the other collections ($country and $city)
The formula in the example is straightforward, allowing you to sort in descending order. But you probably have plenty of ideas for more complex formulas to suit your needs.
$continent.multiSort(Formula($1.value>$1.value2); [$country; $city])
The result is:
"Europe"; "Europe"; "Europe"; "America"; "Africa" "France"; "France"; "Germany"; "US"; "Morocco" "Paris"; "Lyon"; "Eching"; "San Diego"; "Rabat"
Example 4: With complex collections
You can also use it to synchronize collections of objects.
var $name : Collection
var $address : Collection
$name:=[]
$name.push({firstname: "John"; lastname: "Smith"})
$name.push({firstname: "Alain"; lastname: "Martin"})
$name.push({firstname: "Jane"; lastname: "Doe"})
$name.push({firstname: "John"; lastname: "Doe"})
$address:=[]
$address.push({city: "Paris"; country: "France"})
$address.push({city: "Lyon"; country: "France"})
$address.push({city: "Eching"; country: "Germany"})
$address.push({city: "Berlin"; country: "Germany"})
$name.multiSort(Formula($1.value.firstname<$1.value2.firstname); [$address])
The result is:
"Alain Martin"; "Jane Doe"; "John Smith"; "John Doe" "Lyon France"; "Eching Germany"; "Paris France"; "Berlin Germany"
Next…
For more information, please refer to the documentation. You can share your feedback and use cases on the forum.