simple-squiggle

A restricted subset of Squiggle
Log | Files | Refs | README

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;