Although I can write AppleScript solutions, I am not heliocentric about the language and prefer speed and less code over language loyalty.
In that regard, I happen to use Zsh-based handlers where it makes sense to me and provides satisfactory speed over larger AppleScript solutions.
Here is an AppleScript that will reduce a comma-punctuated number string to [m-n] where there are sequential digits present. The first example uses a Zsh function named reduce.
use scripting additions
set s to "1,2,3,4,5,6,8,9,10,11,12,13,15,16,17,18,19,20,21,22,24,28,29,31,32,33,34,36,37,38,39,40,41,42,44,49,51,56,58,60,63,64,65,66,71,72,73,86,91,95,102,119,125,126,133,145,150,152,161,163,167,168"
log (my test(s)) as text
return
on test(s)
return (do shell script "/bin/zsh -s <<'EOF' - " & s's quoted form & "
#!/bin/zsh
# hyphenate sequential numbers in the form m-n
reduce () {
local i=1
argv=(${(nus:,:)1})
while ((i < $#))
do
if ((${argv[i]#*-} + 1 == ${argv[i+1]%-*}))
then
argv[i]=${argv[i]%-*}-${argv[i+1]#*-}
argv[i+1]=()
else
((i++))
fi
done
print ${(j:,:)@}
}
# remove spaces between number results
x=$(reduce \"${1}\" | tr -d '[[:blank:]]')
print ${x}
EOF")
end test
That returns this result:
"1-6,8-13,15-22,24,28-29,31-34,36-42,44,49,51,56,58,60,63-66,71-73,86,91,95,102,119,125-126,133,145,150,152,161,163,167-168"
Enter the Zsh zcompile command. I select only the reduce function code from the above script and save it into a text file named reduce.zsh in an arbitrary named folder location (e.g. ~/bin/zshfx). I change directory to that location and perform the following in the Terminal:
zcompile -M reduce.zsh
This produces the compiled file reduce.zsh.zwc.
You can read about that -M memory mapped option in the zshbuiltins man page for zcompile. Essentially, the zsh function will be mapped to shell memory where multiple instances of the shell will share this function.
Now, one can replace that verbose reduce function in the preceding code example with the just a reference to the reduce function name:
use scripting additions
set s to "1,2,3,4,5,6,8,9,10,11,12,13,15,16,17,18,19,20,21,22,24,28,29,31,32,33,34,36,37,38,39,40,41,42,44,49,51,56,58,60,63,64,65,66,71,72,73,86,91,95,102,119,125,126,133,145,150,152,161,163,167,168"
log (my test(s)) as text
return
on test(s)
return (do shell script "/bin/zsh -s <<'EOF' - " & s's quoted form & "
#!/bin/zsh
# one has run zcompile on reduce.zsh containing the reduce function
# in the ~/bin/zshfx folder
fpath=(/Users/$USER/bin/zshfx $fpath)
autoload -Uz reduce
# the compiled reduce function introduces spaces between items
# so tr cleans that up nicely.
x=$(reduce \"${1}\" | tr -d '[[:blank:]]')
print $x
EOF")
end test
This latter script solution produces the same result as the first script and does so several seconds quicker, since the function text does not need to be parsed in the handler.