simple-squiggle

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

map.js (4040B)


      1 "use strict";
      2 
      3 Object.defineProperty(exports, "__esModule", {
      4   value: true
      5 });
      6 exports.createMap = void 0;
      7 
      8 var _function = require("../../utils/function.js");
      9 
     10 var _factory = require("../../utils/factory.js");
     11 
     12 var name = 'map';
     13 var dependencies = ['typed'];
     14 var createMap = /* #__PURE__ */(0, _factory.factory)(name, dependencies, function (_ref) {
     15   var typed = _ref.typed;
     16 
     17   /**
     18    * Create a new matrix or array with the results of a callback function executed on
     19    * each entry of a given matrix/array.
     20    *
     21    * For each entry of the input, the callback is invoked with three arguments:
     22    * the value of the entry, the index at which that entry occurs, and the full
     23    * matrix/array being traversed. Note that because the matrix/array might be
     24    * multidimensional, the "index" argument is always an array of numbers giving
     25    * the index in each dimension. This is true even for vectors: the "index"
     26    * argument is an array of length 1, rather than simply a number.
     27    *
     28    * Syntax:
     29    *
     30    *    math.map(x, callback)
     31    *
     32    * Examples:
     33    *
     34    *    math.map([1, 2, 3], function(value) {
     35    *      return value * value
     36    *    })  // returns [1, 4, 9]
     37    *
     38    *    // The calling convention for the callback can cause subtleties:
     39    *    math.map([1, 2, 3], math.format)
     40    *    // throws TypeError: map attempted to call 'format(1,[0])' but argument 2 of type Array does not match expected type number or function or Object or string or boolean
     41    *    // [This happens because `format` _can_ take a second argument,
     42    *    // but its semantics don't match that of the 2nd argument `map` provides]
     43    *
     44    *    // To avoid this error, use a function that takes exactly the
     45    *    // desired arguments:
     46    *    math.map([1, 2, 3], x => math.format(x)) // returns ['1', '2', '3']
     47    *
     48    * See also:
     49    *
     50    *    filter, forEach, sort
     51    *
     52    * @param {Matrix | Array} x    The input to iterate on.
     53    * @param {Function} callback
     54    *     The function to call (as described above) on each entry of the input
     55    * @return {Matrix | array}
     56    *     Transformed map of x; always has the same type and shape as x
     57    */
     58   return typed(name, {
     59     'Array, function': _map,
     60     'Matrix, function': function MatrixFunction(x, callback) {
     61       return x.map(callback);
     62     }
     63   });
     64 });
     65 /**
     66  * Map for a multi dimensional array
     67  * @param {Array} array
     68  * @param {Function} callback
     69  * @return {Array}
     70  * @private
     71  */
     72 
     73 exports.createMap = createMap;
     74 
     75 function _map(array, callback) {
     76   // figure out what number of arguments the callback function expects
     77   var args = (0, _function.maxArgumentCount)(callback);
     78 
     79   var recurse = function recurse(value, index) {
     80     if (Array.isArray(value)) {
     81       return value.map(function (child, i) {
     82         // we create a copy of the index array and append the new index value
     83         return recurse(child, index.concat(i));
     84       });
     85     } else {
     86       try {
     87         // invoke the callback function with the right number of arguments
     88         if (args === 1) {
     89           return callback(value);
     90         } else if (args === 2) {
     91           return callback(value, index);
     92         } else {
     93           // 3 or -1
     94           return callback(value, index, array);
     95         }
     96       } catch (err) {
     97         // But maybe the arguments still weren't right
     98         if (err instanceof TypeError && 'data' in err && err.data.category === 'wrongType') {
     99           var newmsg = "map attempted to call '".concat(err.data.fn, "(").concat(value);
    100           var indexString = JSON.stringify(index);
    101 
    102           if (args === 2) {
    103             newmsg += ',' + indexString;
    104           } else if (args !== 1) {
    105             newmsg += ",".concat(indexString, ",").concat(array);
    106           }
    107 
    108           newmsg += ")' but argument ".concat(err.data.index + 1, " of type ");
    109           newmsg += "".concat(err.data.actual, " does not match expected type ");
    110           newmsg += err.data.expected.join(' or ');
    111           throw new TypeError(newmsg);
    112         }
    113 
    114         throw err;
    115       }
    116     }
    117   };
    118 
    119   return recurse(array, []);
    120 }