array-iteration.js 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. var bind = require('../internals/function-bind-context');
  2. var uncurryThis = require('../internals/function-uncurry-this');
  3. var IndexedObject = require('../internals/indexed-object');
  4. var toObject = require('../internals/to-object');
  5. var lengthOfArrayLike = require('../internals/length-of-array-like');
  6. var arraySpeciesCreate = require('../internals/array-species-create');
  7. var push = uncurryThis([].push);
  8. // `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterReject }` methods implementation
  9. var createMethod = function (TYPE) {
  10. var IS_MAP = TYPE == 1;
  11. var IS_FILTER = TYPE == 2;
  12. var IS_SOME = TYPE == 3;
  13. var IS_EVERY = TYPE == 4;
  14. var IS_FIND_INDEX = TYPE == 6;
  15. var IS_FILTER_REJECT = TYPE == 7;
  16. var NO_HOLES = TYPE == 5 || IS_FIND_INDEX;
  17. return function ($this, callbackfn, that, specificCreate) {
  18. var O = toObject($this);
  19. var self = IndexedObject(O);
  20. var boundFunction = bind(callbackfn, that);
  21. var length = lengthOfArrayLike(self);
  22. var index = 0;
  23. var create = specificCreate || arraySpeciesCreate;
  24. var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_REJECT ? create($this, 0) : undefined;
  25. var value, result;
  26. for (;length > index; index++) if (NO_HOLES || index in self) {
  27. value = self[index];
  28. result = boundFunction(value, index, O);
  29. if (TYPE) {
  30. if (IS_MAP) target[index] = result; // map
  31. else if (result) switch (TYPE) {
  32. case 3: return true; // some
  33. case 5: return value; // find
  34. case 6: return index; // findIndex
  35. case 2: push(target, value); // filter
  36. } else switch (TYPE) {
  37. case 4: return false; // every
  38. case 7: push(target, value); // filterReject
  39. }
  40. }
  41. }
  42. return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;
  43. };
  44. };
  45. module.exports = {
  46. // `Array.prototype.forEach` method
  47. // https://tc39.es/ecma262/#sec-array.prototype.foreach
  48. forEach: createMethod(0),
  49. // `Array.prototype.map` method
  50. // https://tc39.es/ecma262/#sec-array.prototype.map
  51. map: createMethod(1),
  52. // `Array.prototype.filter` method
  53. // https://tc39.es/ecma262/#sec-array.prototype.filter
  54. filter: createMethod(2),
  55. // `Array.prototype.some` method
  56. // https://tc39.es/ecma262/#sec-array.prototype.some
  57. some: createMethod(3),
  58. // `Array.prototype.every` method
  59. // https://tc39.es/ecma262/#sec-array.prototype.every
  60. every: createMethod(4),
  61. // `Array.prototype.find` method
  62. // https://tc39.es/ecma262/#sec-array.prototype.find
  63. find: createMethod(5),
  64. // `Array.prototype.findIndex` method
  65. // https://tc39.es/ecma262/#sec-array.prototype.findIndex
  66. findIndex: createMethod(6),
  67. // `Array.prototype.filterReject` method
  68. // https://github.com/tc39/proposal-array-filtering
  69. filterReject: createMethod(7)
  70. };