We need some functions in math.js to check the type of the value. Right now I'm forced to roll my own which would be wierd and buggy. The API should look like :
math.isunit (value:any):boolean
math.isnumber (value:any):boolean
math.isbignumber (value:any):boolean
math.iscomplex (value:any):boolean
math.isfraction (value:any):boolean
math.ismatrix (value:any):boolean
And some more utils to help check validity of input values:
math.isvalid (value:any):boolean .. checks if not
NaNand if not a NaN Unit, Fraction, BigNumber, etc
math.isblank (value:any):boolean .. returns true if the value is0orNaN, or is a0or NaN Unit, Fraction, BigNumber, etc
Do you guys think its a good idea?
Makes sense to add these util functions. We already have math.typeof and some utils like isNumeric and isPositive.
The implementation is easy:
function isUnit (value) {
return value && value.isUnit;
}
function isBigNumber (value) {
return value && value.isBigNumber;
}
// ... etc ...
You could also check using math.typeof, like math.typeof(value) === 'Unit', but that's a bit less efficient.
math.isvalid is interesting but it may be better to name it isNaN, and indeed have it work for numbers, complex numbers, bignumbers, etc. I'm not sure about isBlank, I think it would be better to only offer primitive checks and let the user decide on what he wants combinations of checks (like isNaN, isZero, isFinite, ...)
Here a proposal for a complete list of type checks:
math.typeof(x) returns the type of xmath.isInteger(x) is is an integer numeric valuemath.isNegative(x) x is smaller than zeromath.isNumeric(x) x is a number, BigNumber, Fraction, or booleanmath.isPositive(x) x is larger than zeromath.isZero(x) x is zeromath.isNaN(x)math.isFinite(x)math.isBoolean(x)math.isNumber(x)math.isBigNumber(x)math.isString(x)math.isComplex(x)math.isFraction(x)math.isUnit(x)math.isMatrix(x)math.isArray(x)math.isCollection(x) x is a Matrix or an ArrayLooks great. Can't wait for it.
@josdejong - Any plans to build these into math.js? Would be very useful.
Yes :)
Would you be interested in contributing these functions?
I'll have a go. Can you test these and merge them in if they are fine? No time to do a full PR atm.
In my code I've tackled scalar numbers, probably Units and stuff (via math.equals) and Arrays. Hope there are no more types to handle.
Please keep isValid; rename it but keep it; most of the time you need to check if a value is not NaN and not zero and not Infinity at once, this is a util method for that. Also blank arrays (0 length) show false with isValid.
function isNaN (value) {
// Avoid isNaN. Its behaviour is misleading -- http://stackoverflow.com/questions/8965364/comparing-nan-values-for-equality-in-javascript
// check if value is NaN
if (value !== value || !math.equals(value, value)){
return true;
}
// check if any slot in the array is NaN
if (value instanceof Array){
for (var i=0; i<value.length; i++){
var item=value[i];
if (item !== item || !math.equals(item, item)){
return true;
}
return false;
}
}
// unknown
return false;
}
function isFinite (value) {
// check if value is Infinity
if (value == Number.POSITIVE_INFINITY || value == Number.NEGATIVE_INFINITY){
return false;
}
// check if any slot in the array is Infinity
if (value instanceof Array){
for (var i=0; i<value.length; i++){
var item=value[i];
if (item == Number.POSITIVE_INFINITY || item == Number.NEGATIVE_INFINITY || math.equals(item, Number.POSITIVE_INFINITY) || math.equals(item, Number.NEGATIVE_INFINITY)){
return false;
}
return true;
}
}
// unknown
return true;
}
function isNonZero (value) {
// check non-zero value
if (value == null || value == 0 || math.equals(value, 0)){
return false;
}
// check non-zero array
if (value instanceof Array){
for (var i=0; i<value.length; i++){
var item=value[i];
if (item != null && item != 0 && !math.equals(item, 0)){
return true;
}
return false;
}
}
// unknown
return false;
}
function isValid (value) {
if (value != null && value instanceof Array && value.length == 0){ return false; }
return value != null && value != 0 && !isNaN(value) && !isNonZero(value) && isFinite(value);
}
function isBoolean (value) {
return value === true || value === false; // faster than "typeof"
}
function isNumber (value) {
return value != null && typeof value === "number";
}
function isString (value) {
return value != null && typeof value === "string";
}
function isBigNumber (value) {
return value != null && value.isBigNumber;
}
function isComplex (value) {
return value != null && value.isComplex;
}
function isFraction (value) {
return value != null && value.isFraction;
}
function isUnit (value) {
return value != null && value.isUnit;
}
function isMatrix (value) {
return value != null && value.isMatrix;
}
function isArray (value) {
return value != null && value instanceof Array;
}
function isCollection (value) {
return value != null && (value instanceof Array || value.isMatrix);
}
Thanks. Please note that in JavaScript you have to use Array.isArray(value) instead of value instanceof Array (one of these infamous JS inconsistencies).
I understand your arguments for an isValid function, but looking at your pseudo code already gives a lot of discussion: I could use a utility function which does a check whether values are not null, not NaN, and finite. But I would not want this function to check whether a value is a non-empty matrix or something, and a value 0 typically is "valid" for me too. But in your use cases you _do_ want these checks. I really think it depends a lot on the use case what you want such an isValid function to do and not tot do. So I suggest we leave it up to the user to compose it's own isValid function from primitive functions like isNaN, isFinite, etc.
Has isUnit made it to MathJS?
Hm, there is an isUnit function but it's a bit hidden under math.type.isUnit.
Makes sense to move these functions to the main math namespace instead
Most helpful comment
Hm, there is an isUnit function but it's a bit hidden under math.type.isUnit.
Makes sense to move these functions to the main math namespace instead