I have a task that I want to do with ASObjC but it has me stumped.
I need to verify that every item of an array (which is made from a string) contains a value that can be made into an integer. The following script verifies that an item is not blank, but I don’t know how to verify that an item can be made into an integer. I thought I could employ the integerValue property, but that simply returns 0 if an item is a letter. I can do this with basic AppleScript but would like to stick with ASObjC in this case. Thanks for the help.
use framework "Foundation"
use scripting additions
set theString to current application's NSString's stringWithString:"2022/06/" -- error - OK
set theString to current application's NSString's stringWithString:"2022/06/1a" -- should error - fix
set theString to current application's NSString's stringWithString:"2022/06/01" -- no error - OK
set theArray to (theString's componentsSeparatedByString:"/")
set thePredicate to current application's NSPredicate's predicateWithFormat:"self == ''"
set blankCheck to (theArray's filteredArrayUsingPredicate:thePredicate)'s |count|()
if blankCheck > 0 then error "A blank value"
display dialog "No blank items"
Here’s one way with using the ‘NSScanner’ class.
use framework "Foundation"
set theString to current application's NSString's stringWithString:"2022/06/1a"
set theStringArray to theString's componentsSeparatedByString:"/"
repeat with theValue in theStringArray
set theScanner to (current application's NSScanner's scannerWithString:theValue)
if (theScanner's scanInt:(missing value)) and (theScanner's isAtEnd()) then
log "A Valid Integer String = " & theValue
else
log "Not A Valid Integer String = " & theValue
end if
end repeat
There is probably a way to do it with checking the strings characters in an ‘NSCharacterSet’, but I haven’t checked that out.
Regards Mark
You can also use an ‘NSCharacterSet’ to perform the same as I previously posted.
use scripting additions
use framework "Foundation"
set theString to current application's NSString's stringWithString:"2022/06/1a"
set theStringArray to theString's componentsSeparatedByString:"/"
set nonNumericCharSet to (current application's NSCharacterSet's characterSetWithCharactersInString:"0123456789")'s invertedSet()
repeat with theValue in theStringArray
if (theValue's rangeOfCharacterFromSet:nonNumericCharSet)'s |length|() = 0 then
log "A Valid Integer String = " & theValue
else
log "Not A Valid Integer String = " & theValue
end if
end repeat
I’m sure there are probably a few other ways to it as well, but these two are a good starting point.
Regards Mark
Hi peavine.
This is similar to your original:
use framework "Foundation"
use scripting additions
set theString to current application's NSString's stringWithString:"2022/06/" -- error - OK
set theString to current application's NSString's stringWithString:"2022/06/1a" -- should error - fix
set theString to current application's NSString's stringWithString:"2022/06/01" -- no error - OK
set theArray to (theString's componentsSeparatedByString:"/")
set thePredicate to current application's NSPredicate's predicateWithFormat:"self MATCHES '[0-9]++'"
set allIntable to ((theArray's filteredArrayUsingPredicate:thePredicate)'s isEqualToArray:(theArray)) -- as boolean
Thanks Mark and Nigel for the great suggestions. BTW, I don’t recall every using NSScanner–I’ll have to spend some time with that.
You could also try respondsToSelector:(SEL)aSelector
And pass “integerValue” as
The selector
aSelector = @selector(integerValue)
Or
aSelector = NSSelectorSelectorFromString(@“integerValue”)
Thanks technomorph for the suggestion, but I can’t seem to get it to work. What am I doing wrong?
use framework "Foundation"
use scripting additions
set theString to current application's NSString's stringWithString:"a" --> true
set theString to current application's NSString's stringWithString:"1" --> true
set theResult to theString's respondsToSelector:"integerValue"
My reading of the documentation is that theString’s respondsToSelector:“integerValue” returns whether or not theString’s class responds to or implements the integerValue() selector, not whether or not theString itself can actually be coerced to integer.
Yeah that makes sense.
I think Nigel’s method with the predicate using
A RegEx is way to go.
Could also use (\d+)
Another option would be NSScanner.
Which you can use to also extract the integer
Even if it’s embededd “it will Find 1234 in this string”
https://developer.apple.com/documentation/foundation/nsscanner/1411082-scaninteger
It requires the use of a pointer value which can
Be tricky in AppleScript
This is such an easy thing to do with vanilla AppleScript.
Why do you need to use AppleScriptObjC?
set theString to "2022/06/1a"
set text item delimiters to "/"
set theArray to text items of theString
repeat with myitem in theArray
try
myitem as integer
log "A Valid Integer String = " & myitem
on error
log "Not a Valid Integer String = " & myitem
end try
end repeat
I am working to learn ASObjC and that’s the main reason I requested an AppleScriptObjC solution. I learned from both Mark’s and Nigel’s suggestions, and I appreciate them taking the time to respond to my post.
In my testing, Nigel’s suggestion is significantly faster than basic AppleScript if the list is quite large. In my case, the list was small and there was no compelling reason to use ASObjC.