map.transform.js 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import { isFunctionAssignmentNode, isSymbolNode } from '../../utils/is.js';
  2. import { maxArgumentCount } from '../../utils/function.js';
  3. import { map } from '../../utils/array.js';
  4. import { factory } from '../../utils/factory.js';
  5. import { compileInlineExpression } from './utils/compileInlineExpression.js';
  6. var name = 'map';
  7. var dependencies = ['typed'];
  8. export var createMapTransform = /* #__PURE__ */factory(name, dependencies, _ref => {
  9. var {
  10. typed
  11. } = _ref;
  12. /**
  13. * Attach a transform function to math.map
  14. * Adds a property transform containing the transform function.
  15. *
  16. * This transform creates a one-based index instead of a zero-based index
  17. */
  18. function mapTransform(args, math, scope) {
  19. var x, callback;
  20. if (args[0]) {
  21. x = args[0].compile().evaluate(scope);
  22. }
  23. if (args[1]) {
  24. if (isSymbolNode(args[1]) || isFunctionAssignmentNode(args[1])) {
  25. // a function pointer, like filter([3, -2, 5], myTestFunction)
  26. callback = args[1].compile().evaluate(scope);
  27. } else {
  28. // an expression like filter([3, -2, 5], x > 0)
  29. callback = compileInlineExpression(args[1], math, scope);
  30. }
  31. }
  32. return map(x, callback);
  33. }
  34. mapTransform.rawArgs = true;
  35. // one-based version of map function
  36. var map = typed('map', {
  37. 'Array, function': function ArrayFunction(x, callback) {
  38. return _map(x, callback, x);
  39. },
  40. 'Matrix, function': function MatrixFunction(x, callback) {
  41. return x.create(_map(x.valueOf(), callback, x));
  42. }
  43. });
  44. return mapTransform;
  45. }, {
  46. isTransformFunction: true
  47. });
  48. /**
  49. * Map for a multi dimensional array. One-based indexes
  50. * @param {Array} array
  51. * @param {function} callback
  52. * @param {Array} orig
  53. * @return {Array}
  54. * @private
  55. */
  56. function _map(array, callback, orig) {
  57. // figure out what number of arguments the callback function expects
  58. var argsCount = maxArgumentCount(callback);
  59. function recurse(value, index) {
  60. if (Array.isArray(value)) {
  61. return map(value, function (child, i) {
  62. // we create a copy of the index array and append the new index value
  63. return recurse(child, index.concat(i + 1)); // one based index, hence i + 1
  64. });
  65. } else {
  66. // invoke the (typed) callback function with the right number of arguments
  67. if (argsCount === 1) {
  68. return callback(value);
  69. } else if (argsCount === 2) {
  70. return callback(value, index);
  71. } else {
  72. // 3 or -1
  73. return callback(value, index, orig);
  74. }
  75. }
  76. }
  77. return recurse(array, []);
  78. }