number.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. /*!
  2. * All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
  4. * v1.0.0-beta.82
  5. */
  6. import { numberKeys } from "./key";
  7. export function isValidNumber(numberString) {
  8. return !(!numberString || isNaN(Number(numberString)));
  9. }
  10. export function parseNumberString(numberString) {
  11. if (!numberString || !stringContainsNumbers(numberString)) {
  12. return "";
  13. }
  14. return sanitizeExponentialNumberString(numberString, (nonExpoNumString) => {
  15. let containsDecimal = false;
  16. const result = nonExpoNumString
  17. .split("")
  18. .filter((value, i) => {
  19. if (value.match(/\./g) && !containsDecimal) {
  20. containsDecimal = true;
  21. return true;
  22. }
  23. if (value.match(/\-/g) && i === 0) {
  24. return true;
  25. }
  26. return numberKeys.includes(value);
  27. })
  28. .reduce((string, part) => string + part);
  29. return isValidNumber(result) ? Number(result).toString() : "";
  30. });
  31. }
  32. export function sanitizeDecimalString(decimalString) {
  33. const decimalAtEndOfStringButNotStart = /(?!^\.)\.$/;
  34. return decimalString.replace(decimalAtEndOfStringButNotStart, "");
  35. }
  36. export function sanitizeNegativeString(negativeString) {
  37. const allHyphensExceptTheStart = /(?!^-)-/g;
  38. return negativeString.replace(allHyphensExceptTheStart, "");
  39. }
  40. export function sanitizeLeadingZeroString(zeroString) {
  41. const allLeadingZerosOptionallyNegative = /^([-0])0+(?=\d)/;
  42. return zeroString.replace(allLeadingZerosOptionallyNegative, "$1");
  43. }
  44. export function sanitizeNumberString(numberString) {
  45. return sanitizeExponentialNumberString(numberString, (nonExpoNumString) => {
  46. const sanitizedValue = sanitizeNegativeString(sanitizeDecimalString(sanitizeLeadingZeroString(nonExpoNumString)));
  47. const isNegativeDecimalOnlyZeros = /^-\b0\b\.?0*$/;
  48. return isValidNumber(sanitizedValue)
  49. ? isNegativeDecimalOnlyZeros.test(sanitizedValue)
  50. ? sanitizedValue
  51. : Number(sanitizedValue).toString()
  52. : nonExpoNumString;
  53. });
  54. }
  55. export function sanitizeExponentialNumberString(numberString, func) {
  56. if (!numberString) {
  57. return numberString;
  58. }
  59. const firstE = numberString.toLowerCase().indexOf("e") + 1;
  60. return numberString
  61. .replace(/[eE]*$/g, "")
  62. .substring(0, firstE)
  63. .concat(numberString.slice(firstE).replace(/[eE]/g, ""))
  64. .split(/[eE]/)
  65. .map((section, i) => (i === 1 ? func(section.replace(/\./g, "")) : func(section)))
  66. .join("e")
  67. .replace(/^e/, "1e");
  68. }
  69. function stringContainsNumbers(string) {
  70. return numberKeys.some((number) => string.includes(number));
  71. }