map.js 3.8 KB

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