spreadsheet
typeScript/javascript spreadsheet parser, with formulas.
git clone https://git.vogt.world/spreadsheet.git
Log | Files | README.md
← Commit log
commit
message
Formulas.COUNT written and tested.
author
Ben Vogt <[email protected]>
date
2017-02-07 00:46:10
stats
4 file(s) changed, 60 insertions(+), 0 deletions(-)
files
README.md
src/RawFormulas/RawFormulas.ts
src/RawFormulas/Utils.ts
tests/FormulasTest.ts
  1diff --git a/README.md b/README.md
  2index 1a454a1..b6c62ad 100644
  3--- a/README.md
  4+++ b/README.md
  5@@ -14,6 +14,8 @@ Things I should do.
  6 * SUM_ formulas
  7 * ACCRINT
  8 
  9+### SUM and SUMA should be different, and I'm pretty sure they're currently the same.
 10+
 11 ### Date-Time issues
 12 Here are a couple of the issues with Dates and so on:
 13 * There seem to be a few issues where someone did something sloppy inside formulaJS, and timezones, daylight-savings,
 14diff --git a/src/RawFormulas/RawFormulas.ts b/src/RawFormulas/RawFormulas.ts
 15index 846e7f3..4ba5bf7 100644
 16--- a/src/RawFormulas/RawFormulas.ts
 17+++ b/src/RawFormulas/RawFormulas.ts
 18@@ -56,6 +56,7 @@ import {
 19 } from "./Misc";
 20 import {
 21   checkArgumentsAtLeastLength,
 22+  valueCanCoerceToNumber,
 23   filterOutStringValues,
 24   valueToNumber,
 25   checkArgumentsLength,
 26@@ -93,7 +94,28 @@ var COMPLEX = Formula["COMPLEX"];
 27 var CONCATENATE = Formula["CONCATENATE"];
 28 var CONVERT = Formula["CONVERT"];
 29 var CORREL = Formula["CORREL"];
 30-var COUNT = Formula["COUNT"];
 31+
 32+/**
 33+ * Returns the a count of the number of numeric values in a dataset.
 34+ * @param values The values or ranges to consider when counting.
 35+ * @returns {number} number of numeric values in a dataset.
 36+ * @constructor
 37+ */
 38+var COUNT = function (...values) : number {
 39+  checkArgumentsAtLeastLength(values, 1);
 40+  var count = 0;
 41+  for (var i = 0; i < values.length; i++) {
 42+    if (values[i] instanceof Array) {
 43+      if (values[i].length > 0) {
 44+        count += COUNT.apply(this, values[i]);
 45+      }
 46+    } else if (valueCanCoerceToNumber(values[i])) {
 47+      count++;
 48+    }
 49+  }
 50+  return count;
 51+};
 52+
 53 var COUNTA = Formula["COUNTA"];
 54 var COUNTIF = Formula["COUNTIF"];
 55 var COUNTIFS = Formula["COUNTIFS"];
 56diff --git a/src/RawFormulas/Utils.ts b/src/RawFormulas/Utils.ts
 57index df07e1b..9de85de 100644
 58--- a/src/RawFormulas/Utils.ts
 59+++ b/src/RawFormulas/Utils.ts
 60@@ -8,7 +8,7 @@ import * as ERRORS from "../Errors"
 61  */
 62 function checkArgumentsLength(args: any, length: number) {
 63   if (args.length !== length) {
 64-    throw new CellError(ERRORS.NA_ERROR, "Wrong number of arguments to ABS. Expected 1 arguments, but got " + args.length + " arguments.");
 65+    throw new CellError(ERRORS.NA_ERROR, "Wrong number of arguments to ___. Expected 1 arguments, but got " + args.length + " arguments.");
 66   }
 67 }
 68 
 69@@ -19,7 +19,7 @@ function checkArgumentsLength(args: any, length: number) {
 70  */
 71 function checkArgumentsAtLeastLength(args: any, length: number) {
 72   if (args.length < length) {
 73-    throw new CellError(ERRORS.NA_ERROR, "Wrong number of arguments to ABS. Expected 1 arguments, but got " + args.length + " arguments.");
 74+    throw new CellError(ERRORS.NA_ERROR, "Wrong number of arguments to ___. Expected 1 arguments, but got " + args.length + " arguments.");
 75   }
 76 }
 77 
 78@@ -116,6 +116,26 @@ function valueToNumber(value: any) : number {
 79   return 0;
 80 }
 81 
 82+/**
 83+ * Returns true if we can coerce it to the number type
 84+ * @param value to coerce
 85+ * @returns {boolean} if could be coerced to a number
 86+ */
 87+function valueCanCoerceToNumber(value: any) : boolean {
 88+  if (typeof value === "number" || typeof value === "boolean") {
 89+    return true;
 90+  } else if (typeof value === "string") {
 91+    if (value === "") {
 92+      return false;
 93+    }
 94+    if (value.indexOf(".") > -1) {
 95+      return !isNaN(parseFloat(value));
 96+    }
 97+    return !isNaN(parseInt(value));
 98+  }
 99+  return false;
100+}
101+
102 
103 /**
104  * Converts string values in array to 0
105@@ -164,6 +184,7 @@ function flatten(values: Array<any>) : Array<any> {
106 export {
107   stringValuesToZeros,
108   flatten,
109+  valueCanCoerceToNumber,
110   valueToNumber,
111   valueToString,
112   valueToBoolean,
113diff --git a/tests/FormulasTest.ts b/tests/FormulasTest.ts
114index 3b8cc2c..fd772dd 100644
115--- a/tests/FormulasTest.ts
116+++ b/tests/FormulasTest.ts
117@@ -444,8 +444,19 @@ catchAndAssertEquals(function() {
118 }, ERRORS.NA_ERROR);
119 
120 
121+// Test COUNT
122+assertEquals(COUNT([1, 5, 10, 0]), 4);
123+assertEquals(COUNT(1, 5, 10, 0), 4);
124+assertEquals(COUNT(1, 5, 10, "0"), 4);
125+assertEquals(COUNT(1, 5, 10, ["0", "str"]), 4);
126+assertEquals(COUNT(1, 5, 10, false), 4);
127+assertEquals(COUNT(1, 5, 10, true), 4);
128+assertEquals(COUNT([]), 0);
129+assertEquals(COUNT(["str"]), 0);
130+catchAndAssertEquals(function() {
131+  COUNT();
132+}, ERRORS.NA_ERROR);
133 
134-assertEquals(COUNT([1, 5, 10]), 3);
135 
136 assertEquals(COUNTA(10, 10, 22), 3);
137