diff --git a/contrib/util.arrai b/contrib/util.arrai index fcae78dc..5164aa64 100644 --- a/contrib/util.arrai +++ b/contrib/util.arrai @@ -67,6 +67,7 @@ let reduceFlat = \arr \fn \val reduce(arr, \z \i reduce(i, fn, z), val); # Returns a sequence with any offset and holes removed. let noOffset = \s s rank (:.@); + # Explore constructs a dependency graph by starting at source and calling step # to find adjacent nodes. Deps is the graph constructed so far. # Self-edges are ignored. @@ -95,6 +96,18 @@ let rec _topsort = \graph \sorted \sources }; let topsort = \graph _topsort(graph, [], unimported(graph)); +# NaturalOrder can be used to do a natural ordering of a set of strings +let naturalOrder = + let segment = //re.compile(`\d+|\D+`).match; + let digit = //re.compile(`\d`).match; + \v + let segments = segment(v) >> (.(0) rank (:.@)); + let modCheck = cond { + segments && digit(segments(0)): 0, + _: 1, + }; + segments >>> \i \w cond { (i % 2 = modCheck): //eval.value(w), _: w }; + ( :explore, :filterTree, @@ -106,4 +119,5 @@ let topsort = \graph _topsort(graph, [], unimported(graph)); :reduceObj, :topsort, :unimported, + :naturalOrder, ) diff --git a/contrib/util_test.arrai b/contrib/util_test.arrai index e6993b4d..294e587e 100644 --- a/contrib/util_test.arrai +++ b/contrib/util_test.arrai @@ -33,4 +33,10 @@ let _concat = \z \k \v $`${z}+${k}${v}`; let inline = {:time:2020-06-09:}; util.invokeMacro(time, '2020-06-09') = inline = (day: 9, month: 6, year: 2020) , + + naturalOrder: + let input = {'a2','a10', 'a10a', 'a10b', 'a2a', 'a', '1', '12a', '12', '21', '21a1', '2', '', 'ab', 'a20b1c'}; + let ordered = ['', '1', '2', '12', '12a', '21', '21a1', 'a', 'a2', 'a2a', 'a10', 'a10a', 'a10b', 'a20b1c', 'ab']; + (input orderby util.naturalOrder(.)) = ordered + , )