Function to identify variable type in FIJI? e.g. isString(X) returns boolean, or isType(X) returns string, etc

Hi all,

This seems like a pretty straightforward question. Is there a function or command in the IJ1 language (or another language FIJI is able to read) that would enable me to identify whether a variable is a string, number, etc.? Specifically, I’ve used FIJI to open a csv as a results table. The results consist of objects (rows) that have multiple classifiers (columns) applied to designate the class of the object . Some of these classifiers are wholly numerical (e.g. integers numbered 0-12), others are strings (HC, FTC, VCP, Unknown, Non-object), and others have both (e.g. NA or 0-6). Basically I want to pull these results from different columns and run some manipulations/analyses. FIJI has distinct pull functions for whether the result is numerical, ie. “getResult()”, or string, ie. “getResultString()”, returning an error if “getResult()” is used for strings. A simple “isString()” function would allow me to set up conditionals to bypass this issue. Any help is appreciated!

Hi @pdd2110,

You could try the regex for numbers and until proven otherwise, treat the getResult as string.

matches(string, regex)
Returns true if string matches the specified regular expression. Can be replaced with string.matches(regex) in ImageJ 1.52t or later. See also: startsWith, endsWith, indexOf,replace.

Crude proof of principle, with sort of regex for numbers (YMMV, see the link to regular expressions for a more advanced version of a regex matching a number, here we use all digits, a thousands separating comma, a decimal point, and an Exponent):

run("Blobs (25K)");
makeRectangle(52, 19, 43, 45);
run("Measure");
l=getResultString("Label",1);
a=getResultString("Area",1);
print("l is "+l+", a is "+a);
if(matches(l,"[0-9,.E]+")){
	print("l matches a number");
}else{
	print("l is not a number");
}
if(matches(a,"[0-9,.E]+")){
	print("a matches a number");
}else{
	print("a is not a number");
}

outputs

l is blobs-1.gif, a is 1935
l is not a number
a matches a number

Wrap in a function and call that function isNumber.

This is another solution, a bit crude, but it tells the strings from the numbers:

a="1234C34";
b=123;
c=1*a;
d=1*b;
print(a+" "+isNaN(a));
print(b+" "+isNaN(b));
print(c+" "+isNaN(c));
print(d+" "+isNaN(d));

1234C34 1
123 0
NaN 1
123 0

NaN is commonly used to flag a division by zero result, but as we see, it can also be used for this goal.

Thanks @eljonco!

I was eyeing isNaN(), but it was a bit unclear from the documentation whether it would work (or how to use it for this purpose). I’m actually pretty happy my instincts were right here…

Quick (maybe) follow-up questions:

  1. is “[0-9,.E]+” just a general expression for all numbers? If so, do the contents of this expression change the numbers in the set, e.g. “[0-9]+” for all integers? (I’m having trouble parsing that expression, I guess, but its really intriguing…)
  2. matches(a,"[0-9,.E]+") returns “1” if number and “0” if not a number, whereas isNaN() returns “1” if not a number and “0” if it is a number. Both approaches work with getResultString(). Is there an advantage to using one over the other? Is there another variable type that I’m missing here, where both functions would return “0”?
  3. OK so let’s say I’ve defined the isNumber() function in my macro. Is there a way to add it to a “user-defined functions” list so that I don’t have to paste it at the bottom of each macro?

Thanks again!

Hi @pdd2110,
I don’t feel like going into details on regexes as they live in a world of their own and it is not mine :wink:

Well, a very short reply:

  1. something between [ and ] means “any of these”. + means ‘one or more occurrences’. A dash between two items mean from-to. So 0-9 means all digits, E is used in scientific notation, the comma and point are used for thousands and decimals. I forgot many things, so have a look at that linked page on regexes.

  2. returns 1 means returns TRUE, returns 0 means returns FALSE. 1=true, 0=false. They are boolean and you can goof up when you have an if clause testing for not zero (ie. not false) by throwing it a number not equal to 0 or 1, which you might get away with in some programming laugages. (ie. 16 is not ‘falsey’ in some languages). I haven’t tested it for booleans.

  3. I have no idea. I usually have a bunch of snippets around of which the appropriate go in the bottom of the macro.