GroupBy.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. 'use strict';
  2. var AddValueToKeyedGroup = require('./AddValueToKeyedGroup');
  3. var Call = require('es-abstract/2023/Call');
  4. var GetIterator = require('es-abstract/2023/GetIterator');
  5. var IsCallable = require('es-abstract/2023/IsCallable');
  6. var IteratorClose = require('es-abstract/2023/IteratorClose');
  7. var IteratorStep = require('es-abstract/2023/IteratorStep');
  8. var IteratorValue = require('es-abstract/2023/IteratorValue');
  9. var RequireObjectCoercible = require('es-abstract/2023/RequireObjectCoercible');
  10. var ThrowCompletion = require('es-abstract/2023/ThrowCompletion');
  11. var ToPropertyKey = require('es-abstract/2023/ToPropertyKey');
  12. var maxSafeInteger = require('es-abstract/helpers/maxSafeInteger');
  13. var $TypeError = require('es-errors/type');
  14. module.exports = function GroupBy(items, callbackfn, coercion) {
  15. if (coercion !== 'property' && coercion !== 'zero') {
  16. throw new $TypeError('Assertion failed: `coercion` must be `"property"` or `"zero"`');
  17. }
  18. RequireObjectCoercible(items); // step 1
  19. if (!IsCallable(callbackfn)) { // step 2
  20. throw new $TypeError('`callbackfn` must be callable');
  21. }
  22. var groups = []; // step 3
  23. var iteratorRecord = GetIterator(items, 'sync'); // step 4
  24. var k = 0; // step 5
  25. // eslint-disable-next-line no-constant-condition
  26. while (true) { // step 6
  27. if (k >= maxSafeInteger) { // step 6.a
  28. var error = ThrowCompletion(new $TypeError('Iteration count exceeds the max safe integer value')); // step 6.a.i
  29. return IteratorClose(iteratorRecord, error); // step 6.a.ii
  30. }
  31. var next = IteratorStep(iteratorRecord); // step 6.b
  32. if (!next) { // step 6.c
  33. return groups; // step 6.c.i
  34. }
  35. var value = IteratorValue(next); // step 6.d
  36. var key;
  37. try {
  38. key = Call(callbackfn, undefined, [value, k]); // step 6.e
  39. } catch (e) {
  40. IteratorClose(iteratorRecord, ThrowCompletion(e)); // step 6.f
  41. }
  42. if (coercion === 'property') { // step 6.g
  43. try {
  44. key = ToPropertyKey(key); // step 6.g.i
  45. } catch (e) {
  46. IteratorClose(iteratorRecord, ThrowCompletion(e)); // step 6.g.ii
  47. }
  48. } else {
  49. if (coercion !== 'zero') {
  50. throw new $TypeError('Assertion failed: `coercion` should be `"zero"` here'); // step 6.h.i
  51. }
  52. if (key === 0) { // step 6.h.ii
  53. key = 0; // handle negative zero
  54. }
  55. }
  56. AddValueToKeyedGroup(groups, key, value); // step 6.i
  57. k += 1; // step 6.j
  58. }
  59. };