import Utils from "../Utils.js"; /** * Math operations on numbers. * * @author bwhitn [brian.m.whitney@outlook.com] * @copyright Crown Copyright 2016 * @license Apache-2.0 * * @namespace */ const Arithmetic = { /** * @constant * @default */ DELIM_OPTIONS: ["Line feed", "Space", "Comma", "Semi-colon", "Colon", "CRLF"], /** * Splits a string based on a delimiter and calculates the sum of numbers. * * @param {string} input * @param {Object[]} args * @returns {number} */ runSum: function(input, args) { const val = Arithmetic._sum(Arithmetic._createNumArray(input, args[0])); return typeof(val) === "number" ? val : NaN; }, /** * Splits a string based on a delimiter and subtracts all the numbers. * * @param {string} input * @param {Object[]} args * @returns {number} */ runSub: function(input, args) { let val = Arithmetic._sub(Arithmetic._createNumArray(input, args[0])); return typeof(val) === "number" ? val : NaN; }, /** * Splits a string based on a delimiter and multiplies the numbers. * * @param {string} input * @param {Object[]} args * @returns {number} */ runMulti: function(input, args) { let val = Arithmetic._multi(Arithmetic._createNumArray(input, args[0])); return typeof(val) === "number" ? val : NaN; }, /** * Splits a string based on a delimiter and divides the numbers. * * @param {string} input * @param {Object[]} args * @returns {number} */ runDiv: function(input, args) { let val = Arithmetic._div(Arithmetic._createNumArray(input, args[0])); return typeof(val) === "number" ? val : NaN; }, /** * Splits a string based on a delimiter and computes the mean (average). * * @param {string} input * @param {Object[]} args * @returns {number} */ runMean: function(input, args) { let val = Arithmetic._mean(Arithmetic._createNumArray(input, args[0])); return typeof(val) === "number" ? val : NaN; }, /** * Splits a string based on a delimiter and finds the median. * * @param {string} input * @param {Object[]} args * @returns {number} */ runMedian: function(input, args) { let val = Arithmetic._median(Arithmetic._createNumArray(input, args[0])); return typeof(val) === "number" ? val : NaN; }, /** * splits a string based on a delimiter and computes the standard deviation. * * @param {string} input * @param {Object[]} args * @returns {number} */ runStdDev: function(input, args) { let val = Arithmetic._stdDev(Arithmetic._createNumArray(input, args[0])); return typeof(val) === "number" ? val : NaN; }, /** * Converts a string array to a number array. * * @private * @param {string[]} input * @param {string} delim * @returns {number[]} */ _createNumArray: function(input, delim) { delim = Utils.charRep[delim || "Space"]; let splitNumbers = input.split(delim), numbers = [], num; for (let i = 0; i < splitNumbers.length; i++) { if (splitNumbers[i].indexOf(".") >= 0) { num = parseFloat(splitNumbers[i].trim()); } else { num = parseInt(splitNumbers[i].trim(), 0); } if (!isNaN(num)) { numbers.push(num); } } return numbers; }, /** * Adds an array of numbers and returns the value. * * @private * @param {number[]} data * @returns {number} */ _sum: function(data) { if (data.length > 0) { return data.reduce((acc, curr) => acc + curr); } }, /** * Subtracts an array of numbers and returns the value. * * @private * @param {number[]} data * @returns {number} */ _sub: function(data) { if (data.length > 0) { return data.reduce((acc, curr) => acc - curr); } }, /** * Multiplies an array of numbers and returns the value. * * @private * @param {number[]} data * @returns {number} */ _multi: function(data) { if (data.length > 0) { return data.reduce((acc, curr) => acc * curr); } }, /** * Divides an array of numbers and returns the value. * * @private * @param {number[]} data * @returns {number} */ _div: function(data) { if (data.length > 0) { return data.reduce((acc, curr) => acc / curr); } }, /** * Computes mean of a number array and returns the value. * * @private * @param {number[]} data * @returns {number} */ _mean: function(data) { if (data.length > 0) { return Arithmetic._sum(data) / data.length; } }, /** * Computes median of a number array and returns the value. * * @private * @param {number[]} data * @returns {number} */ _median: function (data) { if ((data.length % 2) === 0) { let first, second; data.sort(function(a, b){ return a - b; }); first = data[Math.floor(data.length / 2)]; second = data[Math.floor(data.length / 2) - 1]; return Arithmetic._mean([first, second]); } else { return data[Math.floor(data.length / 2)]; } }, /** * Computes standard deviation of a number array and returns the value. * * @private * @param {number[]} data * @returns {number} */ _stdDev: function (data) { if (data.length > 0) { let avg = Arithmetic._mean(data); let devSum = 0; for (let i = 0; i < data.length; i++) { devSum += (data[i] - avg) ** 2; } return Math.sqrt(devSum / data.length); } }, }; export default Arithmetic;