subset.js (7347B)
1 import { isIndex } from '../../utils/is.js'; 2 import { clone } from '../../utils/object.js'; 3 import { validateIndex } from '../../utils/array.js'; 4 import { getSafeProperty, setSafeProperty } from '../../utils/customs.js'; 5 import { DimensionError } from '../../error/DimensionError.js'; 6 import { factory } from '../../utils/factory.js'; 7 var name = 'subset'; 8 var dependencies = ['typed', 'matrix']; 9 export var createSubset = /* #__PURE__ */factory(name, dependencies, _ref => { 10 var { 11 typed, 12 matrix 13 } = _ref; 14 15 /** 16 * Get or set a subset of a matrix or string. 17 * 18 * Syntax: 19 * math.subset(value, index) // retrieve a subset 20 * math.subset(value, index, replacement [, defaultValue]) // replace a subset 21 * 22 * Examples: 23 * 24 * // get a subset 25 * const d = [[1, 2], [3, 4]] 26 * math.subset(d, math.index(1, 0)) // returns 3 27 * math.subset(d, math.index([0, 1], 1)) // returns [[2], [4]] 28 * 29 * // replace a subset 30 * const e = [] 31 * const f = math.subset(e, math.index(0, [0, 2]), [5, 6]) // f = [[5, 6]] and e = [[5, 0, 6]] 32 * const g = math.subset(f, math.index(1, 1), 7, 0) // g = [[5, 6], [0, 7]] 33 * 34 * // get submatrix using ranges 35 * const M = [ 36 * [1,2,3], 37 * [4,5,6], 38 * [7,8,9] 39 * ] 40 * math.subset(M, math.index(math.range(0,2), math.range(0,3))) // [[1,2,3],[4,5,6]] 41 * 42 * See also: 43 * 44 * size, resize, squeeze, index 45 * 46 * @param {Array | Matrix | string} matrix An array, matrix, or string 47 * @param {Index} index 48 * For each dimension of the target, specifies an index or a list of 49 * indices to fetch or set. `subset` uses the cartesian product of 50 * the indices specified in each dimension. 51 * @param {*} [replacement] An array, matrix, or scalar. 52 * If provided, the subset is replaced with replacement. 53 * If not provided, the subset is returned 54 * @param {*} [defaultValue=undefined] Default value, filled in on new entries when 55 * the matrix is resized. If not provided, 56 * math.matrix elements will be left undefined. 57 * @return {Array | Matrix | string} Either the retrieved subset or the updated matrix. 58 */ 59 return typed(name, { 60 // get subset 61 'Array, Index': function ArrayIndex(value, index) { 62 var m = matrix(value); 63 var subset = m.subset(index); // returns a Matrix 64 65 return index.isScalar() ? subset : subset.valueOf(); // return an Array (like the input) 66 }, 67 'Matrix, Index': function MatrixIndex(value, index) { 68 return value.subset(index); 69 }, 70 'Object, Index': _getObjectProperty, 71 'string, Index': _getSubstring, 72 // set subset 73 'Array, Index, any': function ArrayIndexAny(value, index, replacement) { 74 return matrix(clone(value)).subset(index, replacement, undefined).valueOf(); 75 }, 76 'Array, Index, any, any': function ArrayIndexAnyAny(value, index, replacement, defaultValue) { 77 return matrix(clone(value)).subset(index, replacement, defaultValue).valueOf(); 78 }, 79 'Matrix, Index, any': function MatrixIndexAny(value, index, replacement) { 80 return value.clone().subset(index, replacement); 81 }, 82 'Matrix, Index, any, any': function MatrixIndexAnyAny(value, index, replacement, defaultValue) { 83 return value.clone().subset(index, replacement, defaultValue); 84 }, 85 'string, Index, string': _setSubstring, 86 'string, Index, string, string': _setSubstring, 87 'Object, Index, any': _setObjectProperty 88 }); 89 }); 90 /** 91 * Retrieve a subset of a string 92 * @param {string} str string from which to get a substring 93 * @param {Index} index An index or list of indices (character positions) 94 * @returns {string} substring 95 * @private 96 */ 97 98 function _getSubstring(str, index) { 99 if (!isIndex(index)) { 100 // TODO: better error message 101 throw new TypeError('Index expected'); 102 } 103 104 if (index.size().length !== 1) { 105 throw new DimensionError(index.size().length, 1); 106 } // validate whether the range is out of range 107 108 109 var strLen = str.length; 110 validateIndex(index.min()[0], strLen); 111 validateIndex(index.max()[0], strLen); 112 var range = index.dimension(0); 113 var substr = ''; 114 range.forEach(function (v) { 115 substr += str.charAt(v); 116 }); 117 return substr; 118 } 119 /** 120 * Replace a substring in a string 121 * @param {string} str string to be replaced 122 * @param {Index} index An index or list of indices (character positions) 123 * @param {string} replacement Replacement string 124 * @param {string} [defaultValue] Default value to be uses when resizing 125 * the string. is ' ' by default 126 * @returns {string} result 127 * @private 128 */ 129 130 131 function _setSubstring(str, index, replacement, defaultValue) { 132 if (!index || index.isIndex !== true) { 133 // TODO: better error message 134 throw new TypeError('Index expected'); 135 } 136 137 if (index.size().length !== 1) { 138 throw new DimensionError(index.size().length, 1); 139 } 140 141 if (defaultValue !== undefined) { 142 if (typeof defaultValue !== 'string' || defaultValue.length !== 1) { 143 throw new TypeError('Single character expected as defaultValue'); 144 } 145 } else { 146 defaultValue = ' '; 147 } 148 149 var range = index.dimension(0); 150 var len = range.size()[0]; 151 152 if (len !== replacement.length) { 153 throw new DimensionError(range.size()[0], replacement.length); 154 } // validate whether the range is out of range 155 156 157 var strLen = str.length; 158 validateIndex(index.min()[0]); 159 validateIndex(index.max()[0]); // copy the string into an array with characters 160 161 var chars = []; 162 163 for (var i = 0; i < strLen; i++) { 164 chars[i] = str.charAt(i); 165 } 166 167 range.forEach(function (v, i) { 168 chars[v] = replacement.charAt(i[0]); 169 }); // initialize undefined characters with a space 170 171 if (chars.length > strLen) { 172 for (var _i = strLen - 1, _len = chars.length; _i < _len; _i++) { 173 if (!chars[_i]) { 174 chars[_i] = defaultValue; 175 } 176 } 177 } 178 179 return chars.join(''); 180 } 181 /** 182 * Retrieve a property from an object 183 * @param {Object} object 184 * @param {Index} index 185 * @return {*} Returns the value of the property 186 * @private 187 */ 188 189 190 function _getObjectProperty(object, index) { 191 if (index.size().length !== 1) { 192 throw new DimensionError(index.size(), 1); 193 } 194 195 var key = index.dimension(0); 196 197 if (typeof key !== 'string') { 198 throw new TypeError('String expected as index to retrieve an object property'); 199 } 200 201 return getSafeProperty(object, key); 202 } 203 /** 204 * Set a property on an object 205 * @param {Object} object 206 * @param {Index} index 207 * @param {*} replacement 208 * @return {*} Returns the updated object 209 * @private 210 */ 211 212 213 function _setObjectProperty(object, index, replacement) { 214 if (index.size().length !== 1) { 215 throw new DimensionError(index.size(), 1); 216 } 217 218 var key = index.dimension(0); 219 220 if (typeof key !== 'string') { 221 throw new TypeError('String expected as index to retrieve an object property'); 222 } // clone the object, and apply the property to the clone 223 224 225 var updated = clone(object); 226 setSafeProperty(updated, key, replacement); 227 return updated; 228 }