-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathlist.sort.fmfn
81 lines (66 loc) · 3.51 KB
/
list.sort.fmfn
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/*
=====================================================
list.sort( values; direction; type )
RETURNS: (list) sorted version of the list
DEPENDENCIES:
VERSION: 1.0
AUTHOR: See notes
NOTES:
Function uses a lot of recursion - be aware of list
size limitations!
Adapted and combined by Matt Petrowsky from
http://www.briandunning.com/cf/593 and
http://www.briandunning.com/cf/594
Compliments to Shaun Flisakowski & Mogens Brun
=====================================================
*/
Let( divider = "||"; // Define the delimiter to divide the two halfs of the whole inbound list(should not be a possible list character)
Case(
PatternCount( values; divider ) = 1; // If the two lists contains the designated divider we'll run the sorting subfunction.
// START SUBFUNCTION
Let([
list.splitpoint = Position( values; divider; 1; 1 ); // Point where list is combined by divider
values.left = Left( values; list.splitpoint - 1 ); // Real left side list
values.right = Right( values; Length( values ) - ( list.splitpoint + Length( divider ) - 1 ) ); // Real right side list
$left.size = ValueCount( values.left );
$right.size = ValueCount( values.right )
];
Case(
$left.size = 0; values.right;
$right.size = 0; values.left;
Let([
$value.left = LeftValues( values.left; 1 );
$value.right = LeftValues( values.right; 1 );
$left.compare = Case(
type = "Number"; Let( $right.compare = GetAsNumber( $value.right ); GetAsNumber( $value.left ) );
type = "Time"; Let( $right.compare = GetAsTime( $value.right ); GetAsTime( $value.left ) );
type = "Date"; Let( $right.compare = GetAsDate( $value.right ); GetAsDate( $value.left ) );
// Default
Let( $right.compare = $value.right; $value.left )
)
];
// Determine sort direction based on supplied parameter. Default to Ascending as most common
If( If( direction = "Dsc"; $left.compare ≥ $right.compare; $left.compare < $right.compare );
$value.left & list.sort( RightValues( values.left; $left.size - 1 ) & divider & values.right; direction; type );
$value.right & list.sort( values.left & divider & RightValues( values.right; $right.size - 1 ); direction; type )
)
)
)
);
// MAIN SORTING FUNCTION
Let(
$list.size = ValueCount( values );
If( $list.size ≤ 1;
values;
Let( [
list.splitpoint = Div( $list.size; 2 ); // Get dividing point to split whole list in half
left.list = LeftValues( values; list.splitpoint ); // Left half of the list
right.list = RightValues( values; $list.size - list.splitpoint ) // Right half of the list
];
// Walk through the two lists comparing values
list.sort( list.sort( left.list; direction; type ) & divider & list.sort(right.list; direction; type ); direction; type )
)
)
)
)
)