odin-js-fundamentals-part-5/node_modules/object.groupby/aos/GroupBy.js

82 lines
2.5 KiB
JavaScript
Raw Normal View History

2024-01-11 08:52:05 +00:00
'use strict';
var GetIntrinsic = require('get-intrinsic');
var AddValueToKeyedGroup = require('./AddValueToKeyedGroup');
var Call = require('es-abstract/2022/Call');
var GetIterator = require('es-abstract/2022/GetIterator');
var IsCallable = require('es-abstract/2022/IsCallable');
var IteratorClose = require('./IteratorClose');
var IteratorStep = require('./IteratorStep');
var IteratorValue = require('es-abstract/2022/IteratorValue');
var maxSafeInteger = require('es-abstract/helpers/maxSafeInteger');
var RequireObjectCoercible = require('es-abstract/2022/RequireObjectCoercible');
var ThrowCompletion = require('es-abstract/2022/ThrowCompletion');
var ToPropertyKey = require('es-abstract/2022/ToPropertyKey');
var $TypeError = GetIntrinsic('%TypeError%');
module.exports = function GroupBy(items, callbackfn, coercion) {
if (coercion !== 'property' && coercion !== 'zero') {
throw new $TypeError('Assertion failed: `coercion` must be `"property"` or `"zero"`');
}
RequireObjectCoercible(items); // step 1
if (!IsCallable(callbackfn)) { // step 2
throw new $TypeError('`callbackfn` must be callable');
}
var groups = []; // step 3
var iterator = GetIterator(items); // step 4
var iteratorRecord = { // TODO: remove this once GetIterator is on ES2023+
'[[Iterator]]': iterator,
'[[NextMethod]]': iterator.next,
'[[Done]]': false // eslint-disable-line sort-keys
};
var k = 0; // step 5
// eslint-disable-next-line no-constant-condition
while (true) { // step 6
if (k >= maxSafeInteger) { // step 6.a
var error = ThrowCompletion(new $TypeError('Iteration count exceeds the max safe integer value')); // step 6.a.i
return IteratorClose(iteratorRecord, error); // step 6.a.ii
}
var next = IteratorStep(iteratorRecord); // step 6.b
if (!next) { // step 6.c
return groups; // step 6.c.i
}
var value = IteratorValue(next); // step 6.d
var key;
try {
key = Call(callbackfn, undefined, [value, k]); // step 6.e
} catch (e) {
IteratorClose(iteratorRecord, ThrowCompletion(e)); // step 6.f
}
if (coercion === 'property') { // step 6.g
try {
key = ToPropertyKey(key); // step 6.g.i
} catch (e) {
IteratorClose(iteratorRecord, ThrowCompletion(e)); // step 6.g.ii
}
} else {
if (coercion !== 'zero') {
throw new $TypeError('Assertion failed: `coercion` should be `"zero"` here'); // step 6.h.i
}
if (key === 0) { // step 6.h.ii
key = 0; // handle negative zero
}
}
AddValueToKeyedGroup(groups, key, value); // step 6.i
k += 1; // step 6.j
}
};