Lets say I have a variable set to this:
set myVar to {"asdf", "qwerty24", "23", "22", "21abc" "20"}
How can I set a variable to the numbers in myVar, including those with text inside of the item–but without keeping the part that is text.
Each item should only contain one number, if an item were to consist of multiple numbers ie "302 303" then the outputted result would preferably be just combined to "302303". Any spaces in the item need to be removed to, just like the text. If each number needs to be an integer so "0abc.1200" needs to have it's period removed and result with "1200". The result would be preferably listed as {"24", "23", "22", "21", "20"}, instead of being listed as {24, 23, 22, 21, 20}.
Best Answer
Objective: To process an AppleScript list of strings so that each string is filtered to remove any non-digit character followed by all leading zeroes. Resultant empty strings are discarded.
Breakdown
property
declarationsA
property
is similar to a variable, except for two differences: properties are persistent, and have global scope; variables are disposed of when a script ends, and default to local scope. I will let you research those terms if you need to, as it's beyond the remit of this answer. I almost never use aproperty
for either of those features I just mentioned. Rather, I use them most often to separate storage of values that I generally intend to remain constant throughout the script (as opposed to variables that can be expected to change at any stage). AppleScript doesn't have a way to declare constants like other languages, so this is just a bastardisation of another construct.Handlers
Handlers in AppleScript can be thought of to be what other languages refer to as a function, and the actual differences are nuanced and mostly academic, with one practical implication being that handlers aren't self-aware so can't report any information about themselves back to you. But, like functions, they receive arguments (or parameters), do something with them, and spit out a result at the end in most cases.
filterCharacters
: this is the core of the script in terms of where the heavy lifting is done. It receives a single piece of text you wish to be filtered, and a list of allowed characters, and removes everything else, i.e. it extracts occurrences of allowed characters in the order they occur. It does this by utilising AppleScript'stext item delimiters
, which you should read about more thoroughly, but essentially deletes all instances of delimiters in the list you supply it, splitting the string into fragments at the points of deletion. So, it's almost performing the opposite function that we want, and can be thought of being a text filter that you supply a list of illegals rather than a list of allowables. Therefore, I use them twice: first to strip out the allowables, leaving only the illegals; then giving that list of illegals back totext item delimiters
, which then get stripped from the original piece of text, thus leaving us only with allowables. Very efficient; avoids iterating through characters in the piece of text.processedNumericalString():
This handler is just a cheap and lazy way to strip off the leading zeroes once the first handler has given us a string containing only digits. It would be arguably more correct to iterate through each digit character until reaching the first non-zero character, deleting the ones that are, with a special case to prevent"0"
being obliterated. But, instead, I just decided to coerce thestring
to anumber
, then back to astring
. A hack that works effectively and one assumes more speedily too (though that's not definitive).The main body of the script
With the two handlers defined at the bottom of the script, all that remains is to iterate through the list of strings, sending each string in turn to each handler. What comes back is the piece of text you desire, which
set the contents of...
is what lets me replace the original item in the list with the new version. I was mindful not to retain empty strings (""
), and theprocessedNumericalString()
handler swaps those out for an AppleScript object calledmissing value
that represents exactly what it says (it's the closest pre-defined AppleScript object to what other languages often callnull
ornil
). Anyway, the important this is it isn't astring
, because the final line of the script's run is:and this does exactly that: any item in the list that is not a
string
(ortext
) class of object is discarded. You can, of course, swap this line for:if you need it assigned to a variable in order to keep using it.
ADDENDUM
The OP added:
OK. Let's bung the main part of the script into another handler:
Place this with the other handlers to keep it separate and out of the way now. The main body of the script is reduced to these two lines, where I've used the identifier
myVar
instead ofL
just for clarity:Now, wherever
myVar
in your script gets updated/changed, you follow it with a call to this new handler, as I've illustrated here.Just be clear about how I've delineated the different "parts" of the script: keep the
property
declarations at the top—don't put them inside your repeat loop; also don't put the handler declarations inside the repeat loop—I put all of mine at the bottom of the script, where I've marked a line and headed a section only for handlers. The "main body" of the script (despite now only being two lines here) is what your code will occupy, so keep things neat and grouped (it's why I separate theproperty
declarations from the main body by two paragraph breaks instead of just one).