transform.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. var arrayEach = require('./_arrayEach'),
  2. baseCreate = require('./_baseCreate'),
  3. baseForOwn = require('./_baseForOwn'),
  4. baseIteratee = require('./_baseIteratee'),
  5. getPrototype = require('./_getPrototype'),
  6. isArray = require('./isArray'),
  7. isFunction = require('./isFunction'),
  8. isObject = require('./isObject'),
  9. isTypedArray = require('./isTypedArray');
  10. /**
  11. * An alternative to `_.reduce`; this method transforms `object` to a new
  12. * `accumulator` object which is the result of running each of its own
  13. * enumerable string keyed properties thru `iteratee`, with each invocation
  14. * potentially mutating the `accumulator` object. If `accumulator` is not
  15. * provided, a new object with the same `[[Prototype]]` will be used. The
  16. * iteratee is invoked with four arguments: (accumulator, value, key, object).
  17. * Iteratee functions may exit iteration early by explicitly returning `false`.
  18. *
  19. * @static
  20. * @memberOf _
  21. * @since 1.3.0
  22. * @category Object
  23. * @param {Object} object The object to iterate over.
  24. * @param {Function} [iteratee=_.identity] The function invoked per iteration.
  25. * @param {*} [accumulator] The custom accumulator value.
  26. * @returns {*} Returns the accumulated value.
  27. * @example
  28. *
  29. * _.transform([2, 3, 4], function(result, n) {
  30. * result.push(n *= n);
  31. * return n % 2 == 0;
  32. * }, []);
  33. * // => [4, 9]
  34. *
  35. * _.transform({ 'a': 1, 'b': 2, 'c': 1 }, function(result, value, key) {
  36. * (result[value] || (result[value] = [])).push(key);
  37. * }, {});
  38. * // => { '1': ['a', 'c'], '2': ['b'] }
  39. */
  40. function transform(object, iteratee, accumulator) {
  41. var isArr = isArray(object) || isTypedArray(object);
  42. iteratee = baseIteratee(iteratee, 4);
  43. if (accumulator == null) {
  44. if (isArr || isObject(object)) {
  45. var Ctor = object.constructor;
  46. if (isArr) {
  47. accumulator = isArray(object) ? new Ctor : [];
  48. } else {
  49. accumulator = isFunction(Ctor) ? baseCreate(getPrototype(object)) : {};
  50. }
  51. } else {
  52. accumulator = {};
  53. }
  54. }
  55. (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) {
  56. return iteratee(accumulator, value, index, object);
  57. });
  58. return accumulator;
  59. }
  60. module.exports = transform;