I have a list extracted from the web that is normally numbers if any element is not I want to replace it with a zero. My 1st example below is how I achieve that, my issue is when I try it using and IF then block to check if a variable is a number it does not work. I would like to understand what I am missing in construction.
set CheckList to {45, "Neutral", "20"}
log CheckList
repeat with Cnt from 1 to 3
try
set item Cnt of CheckList to item Cnt of CheckList as number
on error
set item Cnt of CheckList to "0"
end try
end repeat
log CheckList
this is an example of what I have tried which treats each occurrence as if it is not a number
set CheckList to {45, "Neutral", "20"}
log CheckList
repeat with Cnt from 1 to 3
if (item Cnt of CheckList) is not number then set item Cnt of CheckList to 0
end repeat
log CheckList
The log result is (*0,0,0"), it has treated every instance as if it is not a number
Here is how to check if the items of the list is numbers. I have to go at work now.
set CheckList to {45, "Neutral", "20"}
log CheckList
repeat with Cnt from 1 to count CheckList
if class of (item Cnt of CheckList) is not in {integer, real} then set item Cnt of CheckList to 0
end repeat
log CheckList
Thank you very much, however still have a question if you don’t mind. Your solution fixes the issue when the variable is definitely number but not when it looks like a string and I need to copy both possibilities. In fact the example I posted had one variable as a number but all the variables I retrieve from the web are like “25” the last example in my post.
I may have mislead by saying what I extract is numbers but they all come across as strings “25” etc
set checkList to {45, "Neutral", "20"}
set checkList2 to {}
repeat with i from 1 to count of checkList
set thisItem to item i of checkList
try
set end of checkList2 to thisItem as number
on error errMsg number errNum
set end of checkList2 to 0
end try
end repeat
log checkList
log checkList2
Thanks for getting back to me, however if you look at the 1st example in my original post that is basically what I have been doing. I was amongst other things trying to shorten the routine.
KniazidisR suggestion did shorten it but did not catch variables in the string “20” that looked like a string not a number.
set CheckList to {45, "Neutral", "20"}
log CheckList
repeat with Cnt from 1 to count CheckList
try
set item Cnt of CheckList to item Cnt of CheckList as number
on error
if class of (item Cnt of CheckList) is not in {integer, real} then set item Cnt of CheckList to 0
end try
end repeat
log CheckList
MitchBVI. There are several reasons why your second script doesn’t work as expected:
It tests whether a string or integer is equal to a class (i.e. number). That will always return false.
You could modify the script to test whether the class of the string or integer is equal to the class number, but that will always return false for the reasons stated in the section of the AppleScript Language quoted below.
Your first script seems to work fine. However, the following is a tiny bit more compact and may fit your requirements (if I understand them correctly):
set CheckList to {45, "Neutral", "20"}
repeat with anItem in CheckList
try
set contents of anItem to anItem as number
on error
set contents of anItem to 0
end try
end repeat
CheckList --> {45, 0, 20}
From the AppleScript Language Guide:
NUMBER. An abstract class that can represent an integer or a real. There is never an object whose class is number; the actual class of a "number" object is always one of the more specific types, integer or real.
There is no such class in AppleScript as string-number. Therefore, until you try to coerce a string into a number, you cannot check if a string is a number. That is, you can’t do without a try block. You have already done the best check yourself in your example 1, and @peavine has improved your example to perfection.
Now, I don’t understand why you are converting purely string elements to 0. It is more logical to assume that you do not need them and it would be better to remove them completely from the list. If my assumption is correct, then here is another variation of the script:
set CheckList to {45, "Neutral", "20"}
repeat with anItem in CheckList
try
set contents of anItem to anItem as number
end try
end repeat
set ChekList to numbers of CheckList
Peavine, I now understand the problem I had. Your suggestion is very similar to what I have been doing and does the job.
KniazidisR, I understand your solution, unfortunately my post may have been misleading as I was trying to cover all possibilities (number, string , number as string) but in fact I need them all to be numbers even if zero, as in execution I am adding those groups together in various ways.
Importantly I have learned something about numbers I did not know before.