Intelligent sorting: NEW WINNER Dick Kriesel
FlexibleLearning
admin at FlexibleLearning.com
Thu Jul 8 16:45:49 EDT 2010
This solution from Dick Kriesel is more accurate than any other solution so
far (to an unliminted depth for all practical purposes) and its speed is
comparable with the best to date. Yes it is long, but the demands for an
accurate intelligent sort require some heavy duty parsing. Breaking each
lines into sub-components is indeed the way to go, optimised by 'for each'.
The solution is clearly annotated and sorting by the parallel array keys of
each line is, in my view, a stroke of genius. The only, and quite
understandable, limitation that I can determine is special-formatted
sub-components such as dateTime, but within the parameters of the sample
data expectations it excels. Well done, Dick.
Save this somewhere like the Scripter's Scrapbook for when you need it. As
always, watch out for line-wraps...
function sortMe tData
sort_a1a tData
return tData
end sortMe
command sort_a1a @tData, tSortDelimiter, tOrigin -- note: sort tData
respecting chunks of digits
--| By Dick Kriesel [dick.kriesel at mail.com]
local tCharPrev, tDigits, tNonDigits, tSortKey, tSortKeys
if tSortDelimiter is empty then
put numToChar(8) into tSortDelimiter
end if
if tOrigin is empty then
put 1000000 into tOrigin
-- note: tOrigin = 1000000 enables alphabetic sorting for positive
integers up to 9,999,999
-- note: the caller can enable sorting larger numbers, or can reduce the
number of characters that will be sorted
end if
/*
Step through tData, separating chunks of digits from chunks of other
characters.
For each character that's an integer, append it to a variable that holds
only digits.
For each character that's not an integer, append it to a variable that
holds no digits.
When a character is an integer, but the previous character wasn't, append
the string of
non-digits to the line's sort key.
When a character is not an integer, but the previous character was, add
the origin to the
string of digits and append the sum to the line's sort key.
*/
repeat for each line tLine in tData
put empty into tCharPrev
put empty into tDigits -- note: tDigits tracks the most recent digits
put empty into tNonDigits -- note: tNonDigits tracks the most recent
characters other than digits
put empty into tSortKey
repeat for each char tChar in tLine
if tChar is an integer then
if tCharPrev is an integer then
put tChar after tDigits
else
put tChar into tDigits
if tNonDigits is not empty then
put tNonDigits & tSortDelimiter after tSortKey
put empty into tNonDigits
end if
end if
else
if tCharPrev is an integer then
put tChar into tNonDigits
put tOrigin + tDigits & tSortDelimiter after tSortKey
put empty into tDigits
else
put tChar after tNonDigits
end if
end if
put tChar into tCharPrev
end repeat
if tDigits is not empty then
put tOrigin + tDigits after tSortKey
else if tNonDigits is not empty then
put tNonDigits after tSortKey
end if
put tSortKey into tSortKeys[tLine]
end repeat
sort tData by tSortKeys[each]
end sort_a1a
Hugh Senior
FLCo
More information about the use-livecode
mailing list