numberCast<T extends num> function
T
numberCast<T extends num>(
- dynamic obj
Cast obj
to a numeric type.
Conversions:
- num: Converts using it's own built in systems.
null
: return0
.- bool:
false
returns0
.true
returns1
.
- String:
- Firstly, attempts conversion to double, if fails, then will continue on.
- If it's length is zero then will return
0
. - If length isn't zero, then will add up all char codes and divide it by the length of the string.
- BaseRadix: Returns BaseRadix.number.
- Points: Returns Points.total.
- Other:
- Firstly, will check
obj
for atoDouble()
ortoInt()
functions. - If they don't exist, then will take
obj
`s string representation and call numberCast on it for the return.
- Firstly, will check
If obj
is failed to be converted to a numeric value,
then an ArgumentError is thrown.
Implementation
T numberCast<T extends num>(dynamic obj) {
// If obj is already the same type as T, then just return it.
if (obj is T) return obj;
// Convert obj to a numeric value.
num? n;
if (obj is num) n = obj;
if (obj == null || obj == false) n = 0;
if (obj == true) n = 1;
if (obj is Points) n = obj.total;
if (obj is BaseRadix) n = obj.number;
if (obj is String) {
n = double.tryParse(obj);
if (n == null) {
if (obj.isEmpty) {
n = 0;
} else {
n = obj.codeUnits.reduce((a, b) => a+b) / obj.length;
}
}
}
// Check to see if obj was able to be turned into a numeric,
// if it wasn't then check for toDouble() and toInt() functions,
// if not present then use obj's string representation.
if (n == null) {
try {
n = obj.toDouble();
} on NoSuchMethodError {
try {
n = obj.toInt();
} on NoSuchMethodError {
return numberCast<T>(obj.toString());
}
}
// If n is some how null, then throw argument error.
if (n == null) throw ArgumentError.value(obj, 'obj', 'Cannot convert to numeric value');
}
// ensure that n is the correct numeric type.
if (T is int) return n.toInt() as T;
if (T is double) return n.toDouble() as T;
// Falls to here only because T isn't a known extention of num
// or is num itself.
return n as T;
}