UNPKG

mathjs

Version:

Math.js is an extensive math library for JavaScript and Node.js. It features a flexible expression parser and offers an integrated solution to work with numbers, big numbers, complex numbers, units, and matrices.

191 lines (170 loc) 5.98 kB
module.exports = function (math) { var util = require('../../util/index'), Matrix = require('../../type/Matrix'), Index = require('../../type/Index'), array = util.array, isString = util.string.isString, isArray = Array.isArray; /** * Get or set a subset of a matrix or string * * Usage: * // retrieve subset: * var subset = math.subset(value, index) * * // replace subset: * var value = math.subset(value, index, replacement [, defaultValue]) * * Where: * {Array | Matrix | String} value An array, matrix, or string * {Index} index An index containing ranges for each * dimension * {*} replacement An array, matrix, or scalar * {*} [defaultValue] Default value, filled in on new entries when * the matrix is resized. If not provided, * new matrix elements will be left undefined. * @param args * @return res */ math.subset = function subset (args) { switch (arguments.length) { case 2: // get subset return _getSubset(arguments[0], arguments[1]); // intentional fall through case 3: // set subset case 4: // set subset with default value return _setSubset(arguments[0], arguments[1], arguments[2], arguments[3]); default: // wrong number of arguments throw new math.error.ArgumentsError('subset', arguments.length, 2, 4); } }; /** * Retrieve a subset of an value such as an Array, Matrix, or String * @param {Array | Matrix | String} value Object from which to get a subset * @param {Index} index An index containing ranges for each * dimension * @returns {Array | Matrix | *} subset * @private */ function _getSubset(value, index) { var m, subset; if (isArray(value)) { m = new Matrix(value); subset = m.subset(index); return subset.valueOf(); } else if (value instanceof Matrix) { return value.subset(index); } else if (isString(value)) { return _getSubstring(value, index); } else { throw new math.error.UnsupportedTypeError('subset', math['typeof'](value)); } } /** * Retrieve a subset of a string * @param {String} str String from which to get a substring * @param {Index} index An index containing ranges for each dimension * @returns {string} substring * @private */ function _getSubstring(str, index) { if (!(index instanceof Index)) { // TODO: better error message throw new TypeError('Index expected'); } if (index.size().length != 1) { throw new math.error.DimensionError(index.size().length, 1); } var range = index.range(0); var substr = ''; var strLen = str.length; range.forEach(function (v) { array.validateIndex(v, strLen); substr += str.charAt(v); }); return substr; } /** * Replace a subset in an value such as an Array, Matrix, or String * @param {Array | Matrix | String} value Object to be replaced * @param {Index} index An index containing ranges for each * dimension * @param {Array | Matrix | *} replacement * @param {*} [defaultValue] Default value, filled in on new entries when * the matrix is resized. If not provided, * new matrix elements will be left undefined. * @returns {*} result * @private */ function _setSubset(value, index, replacement, defaultValue) { var m; if (isArray(value)) { m = new Matrix(math.clone(value)); m.subset(index, replacement, defaultValue); return m.valueOf(); } else if (value instanceof Matrix) { return value.clone().subset(index, replacement, defaultValue); } else if (isString(value)) { return _setSubstring(value, index, replacement, defaultValue); } else { throw new math.error.UnsupportedTypeError('subset', math['typeof'](value)); } } /** * Replace a substring in a string * @param {String} str String to be replaced * @param {Index} index An index containing ranges for each dimension * @param {String} replacement Replacement string * @param {String} [defaultValue] Default value to be uses when resizing * the string. is ' ' by default * @returns {string} result * @private */ function _setSubstring(str, index, replacement, defaultValue) { if (!(index instanceof Index)) { // TODO: better error message throw new TypeError('Index expected'); } if (index.size().length != 1) { throw new math.error.DimensionError(index.size().length, 1); } if (defaultValue !== undefined) { if (!isString(defaultValue) || defaultValue.length !== 1) { throw new TypeError('Single character expected as defaultValue'); } } else { defaultValue = ' '; } var range = index.range(0); var len = range.size()[0]; if (len != replacement.length) { throw new math.error.DimensionError(range.size()[0], replacement.length); } // copy the string into an array with characters var strLen = str.length; var chars = []; for (var i = 0; i < strLen; i++) { chars[i] = str.charAt(i); } range.forEach(function (v, i) { array.validateIndex(v); chars[v] = replacement.charAt(i); }); // initialize undefined characters with a space if (chars.length > strLen) { for (i = strLen - 1, len = chars.length; i < len; i++) { if (!chars[i]) { chars[i] = defaultValue; } } } return chars.join(''); } };