range.js (8064B)
1 "use strict"; 2 3 Object.defineProperty(exports, "__esModule", { 4 value: true 5 }); 6 exports.createRange = void 0; 7 8 var _factory = require("../../utils/factory.js"); 9 10 var _noop = require("../../utils/noop.js"); 11 12 var name = 'range'; 13 var dependencies = ['typed', 'config', '?matrix', '?bignumber', 'smaller', 'smallerEq', 'larger', 'largerEq']; 14 var createRange = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) { 15 var typed = _ref.typed, 16 config = _ref.config, 17 matrix = _ref.matrix, 18 bignumber = _ref.bignumber, 19 smaller = _ref.smaller, 20 smallerEq = _ref.smallerEq, 21 larger = _ref.larger, 22 largerEq = _ref.largerEq; 23 24 /** 25 * Create an array from a range. 26 * By default, the range end is excluded. This can be customized by providing 27 * an extra parameter `includeEnd`. 28 * 29 * Syntax: 30 * 31 * math.range(str [, includeEnd]) // Create a range from a string, 32 * // where the string contains the 33 * // start, optional step, and end, 34 * // separated by a colon. 35 * math.range(start, end [, includeEnd]) // Create a range with start and 36 * // end and a step size of 1. 37 * math.range(start, end, step [, includeEnd]) // Create a range with start, step, 38 * // and end. 39 * 40 * Where: 41 * 42 * - `str: string` 43 * A string 'start:end' or 'start:step:end' 44 * - `start: {number | BigNumber}` 45 * Start of the range 46 * - `end: number | BigNumber` 47 * End of the range, excluded by default, included when parameter includeEnd=true 48 * - `step: number | BigNumber` 49 * Step size. Default value is 1. 50 * - `includeEnd: boolean` 51 * Option to specify whether to include the end or not. False by default. 52 * 53 * Examples: 54 * 55 * math.range(2, 6) // [2, 3, 4, 5] 56 * math.range(2, -3, -1) // [2, 1, 0, -1, -2] 57 * math.range('2:1:6') // [2, 3, 4, 5] 58 * math.range(2, 6, true) // [2, 3, 4, 5, 6] 59 * 60 * See also: 61 * 62 * ones, zeros, size, subset 63 * 64 * @param {*} args Parameters describing the ranges `start`, `end`, and optional `step`. 65 * @return {Array | Matrix} range 66 */ 67 return typed(name, { 68 // TODO: simplify signatures when typed-function supports default values and optional arguments 69 // TODO: a number or boolean should not be converted to string here 70 string: _strRange, 71 'string, boolean': _strRange, 72 'number, number': function numberNumber(start, end) { 73 return _out(_rangeEx(start, end, 1)); 74 }, 75 'number, number, number': function numberNumberNumber(start, end, step) { 76 return _out(_rangeEx(start, end, step)); 77 }, 78 'number, number, boolean': function numberNumberBoolean(start, end, includeEnd) { 79 return includeEnd ? _out(_rangeInc(start, end, 1)) : _out(_rangeEx(start, end, 1)); 80 }, 81 'number, number, number, boolean': function numberNumberNumberBoolean(start, end, step, includeEnd) { 82 return includeEnd ? _out(_rangeInc(start, end, step)) : _out(_rangeEx(start, end, step)); 83 }, 84 'BigNumber, BigNumber': function BigNumberBigNumber(start, end) { 85 var BigNumber = start.constructor; 86 return _out(_bigRangeEx(start, end, new BigNumber(1))); 87 }, 88 'BigNumber, BigNumber, BigNumber': function BigNumberBigNumberBigNumber(start, end, step) { 89 return _out(_bigRangeEx(start, end, step)); 90 }, 91 'BigNumber, BigNumber, boolean': function BigNumberBigNumberBoolean(start, end, includeEnd) { 92 var BigNumber = start.constructor; 93 return includeEnd ? _out(_bigRangeInc(start, end, new BigNumber(1))) : _out(_bigRangeEx(start, end, new BigNumber(1))); 94 }, 95 'BigNumber, BigNumber, BigNumber, boolean': function BigNumberBigNumberBigNumberBoolean(start, end, step, includeEnd) { 96 return includeEnd ? _out(_bigRangeInc(start, end, step)) : _out(_bigRangeEx(start, end, step)); 97 } 98 }); 99 100 function _out(arr) { 101 if (config.matrix === 'Matrix') { 102 return matrix ? matrix(arr) : (0, _noop.noMatrix)(); 103 } 104 105 return arr; 106 } 107 108 function _strRange(str, includeEnd) { 109 var r = _parse(str); 110 111 if (!r) { 112 throw new SyntaxError('String "' + str + '" is no valid range'); 113 } 114 115 var fn; 116 117 if (config.number === 'BigNumber') { 118 if (bignumber === undefined) { 119 (0, _noop.noBignumber)(); 120 } 121 122 fn = includeEnd ? _bigRangeInc : _bigRangeEx; 123 return _out(fn(bignumber(r.start), bignumber(r.end), bignumber(r.step))); 124 } else { 125 fn = includeEnd ? _rangeInc : _rangeEx; 126 return _out(fn(r.start, r.end, r.step)); 127 } 128 } 129 /** 130 * Create a range with numbers. End is excluded 131 * @param {number} start 132 * @param {number} end 133 * @param {number} step 134 * @returns {Array} range 135 * @private 136 */ 137 138 139 function _rangeEx(start, end, step) { 140 var array = []; 141 var x = start; 142 143 if (step > 0) { 144 while (smaller(x, end)) { 145 array.push(x); 146 x += step; 147 } 148 } else if (step < 0) { 149 while (larger(x, end)) { 150 array.push(x); 151 x += step; 152 } 153 } 154 155 return array; 156 } 157 /** 158 * Create a range with numbers. End is included 159 * @param {number} start 160 * @param {number} end 161 * @param {number} step 162 * @returns {Array} range 163 * @private 164 */ 165 166 167 function _rangeInc(start, end, step) { 168 var array = []; 169 var x = start; 170 171 if (step > 0) { 172 while (smallerEq(x, end)) { 173 array.push(x); 174 x += step; 175 } 176 } else if (step < 0) { 177 while (largerEq(x, end)) { 178 array.push(x); 179 x += step; 180 } 181 } 182 183 return array; 184 } 185 /** 186 * Create a range with big numbers. End is excluded 187 * @param {BigNumber} start 188 * @param {BigNumber} end 189 * @param {BigNumber} step 190 * @returns {Array} range 191 * @private 192 */ 193 194 195 function _bigRangeEx(start, end, step) { 196 var zero = bignumber(0); 197 var array = []; 198 var x = start; 199 200 if (step.gt(zero)) { 201 while (smaller(x, end)) { 202 array.push(x); 203 x = x.plus(step); 204 } 205 } else if (step.lt(zero)) { 206 while (larger(x, end)) { 207 array.push(x); 208 x = x.plus(step); 209 } 210 } 211 212 return array; 213 } 214 /** 215 * Create a range with big numbers. End is included 216 * @param {BigNumber} start 217 * @param {BigNumber} end 218 * @param {BigNumber} step 219 * @returns {Array} range 220 * @private 221 */ 222 223 224 function _bigRangeInc(start, end, step) { 225 var zero = bignumber(0); 226 var array = []; 227 var x = start; 228 229 if (step.gt(zero)) { 230 while (smallerEq(x, end)) { 231 array.push(x); 232 x = x.plus(step); 233 } 234 } else if (step.lt(zero)) { 235 while (largerEq(x, end)) { 236 array.push(x); 237 x = x.plus(step); 238 } 239 } 240 241 return array; 242 } 243 /** 244 * Parse a string into a range, 245 * The string contains the start, optional step, and end, separated by a colon. 246 * If the string does not contain a valid range, null is returned. 247 * For example str='0:2:11'. 248 * @param {string} str 249 * @return {{start: number, end: number, step: number} | null} range Object containing properties start, end, step 250 * @private 251 */ 252 253 254 function _parse(str) { 255 var args = str.split(':'); // number 256 257 var nums = args.map(function (arg) { 258 // use Number and not parseFloat as Number returns NaN on invalid garbage in the string 259 return Number(arg); 260 }); 261 var invalid = nums.some(function (num) { 262 return isNaN(num); 263 }); 264 265 if (invalid) { 266 return null; 267 } 268 269 switch (nums.length) { 270 case 2: 271 return { 272 start: nums[0], 273 end: nums[1], 274 step: 1 275 }; 276 277 case 3: 278 return { 279 start: nums[0], 280 end: nums[2], 281 step: nums[1] 282 }; 283 284 default: 285 return null; 286 } 287 } 288 }); 289 exports.createRange = createRange;