applySpec.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. import _curry1 from "./internal/_curry1.js";
  2. import _isArray from "./internal/_isArray.js";
  3. import apply from "./apply.js";
  4. import curryN from "./curryN.js";
  5. import max from "./max.js";
  6. import pluck from "./pluck.js";
  7. import reduce from "./reduce.js";
  8. import keys from "./keys.js";
  9. import values from "./values.js"; // Use custom mapValues function to avoid issues with specs that include a "map" key and R.map
  10. // delegating calls to .map
  11. function mapValues(fn, obj) {
  12. return _isArray(obj) ? obj.map(fn) : keys(obj).reduce(function (acc, key) {
  13. acc[key] = fn(obj[key]);
  14. return acc;
  15. }, {});
  16. }
  17. /**
  18. * Given a spec object recursively mapping properties to functions, creates a
  19. * function producing an object of the same structure, by mapping each property
  20. * to the result of calling its associated function with the supplied arguments.
  21. *
  22. * @func
  23. * @memberOf R
  24. * @since v0.20.0
  25. * @category Function
  26. * @sig {k: ((a, b, ..., m) -> v)} -> ((a, b, ..., m) -> {k: v})
  27. * @param {Object} spec an object recursively mapping properties to functions for
  28. * producing the values for these properties.
  29. * @return {Function} A function that returns an object of the same structure
  30. * as `spec', with each property set to the value returned by calling its
  31. * associated function with the supplied arguments.
  32. * @see R.converge, R.juxt
  33. * @example
  34. *
  35. * const getMetrics = R.applySpec({
  36. * sum: R.add,
  37. * nested: { mul: R.multiply }
  38. * });
  39. * getMetrics(2, 4); // => { sum: 6, nested: { mul: 8 } }
  40. * @symb R.applySpec({ x: f, y: { z: g } })(a, b) = { x: f(a, b), y: { z: g(a, b) } }
  41. */
  42. var applySpec =
  43. /*#__PURE__*/
  44. _curry1(function applySpec(spec) {
  45. spec = mapValues(function (v) {
  46. return typeof v == 'function' ? v : applySpec(v);
  47. }, spec);
  48. return curryN(reduce(max, 0, pluck('length', values(spec))), function () {
  49. var args = arguments;
  50. return mapValues(function (f) {
  51. return apply(f, args);
  52. }, spec);
  53. });
  54. });
  55. export default applySpec;