skutter
Version:
Skutter: Opinionated BDD Browser based test framework
58 lines (57 loc) • 2.68 kB
JavaScript
;
const Lazy = require("lazy.js");
class EvenDistributor {
static distributeBasedOnContent(containers, contentFn, division) {
if (!containers) {
throw new Error("[Distributor].[distributeBasedOnContent] containers is not specified.");
}
if (!contentFn) {
throw new Error("[Distributor].[distributeBasedOnContent] contentFn is not specified.");
}
if (!division) {
throw new Error("[Distributor].[distributeBasedOnContent] division is not specified.");
}
let mappedContainers = Lazy(containers).map(contentFn).toArray();
let totalContents = Lazy(mappedContainers).map((x) => { return x.length; }).sum();
let targetContentPerDivision = Math.ceil(totalContents / division);
let sortedContainers = Lazy(containers).sortBy((container) => {
return contentFn(container).length;
}, true).toArray();
let divisionBuckets = [];
for (let divisionSetupIndex = 0; divisionSetupIndex < division; divisionSetupIndex++) {
let container = sortedContainers.shift();
if (container === undefined) {
divisionBuckets.push({
count: 0,
containers: []
});
}
else {
divisionBuckets.push({
count: contentFn(container).length,
containers: [container]
});
}
}
divisionBuckets = Lazy(divisionBuckets).sortBy((bucket) => { return bucket.count; }).toArray();
for (let divisionBucketIndex = 0; divisionBucketIndex < division; divisionBucketIndex++) {
let divisionBucket = divisionBuckets[divisionBucketIndex];
if (divisionBucket.count > targetContentPerDivision) {
continue;
}
for (let sortedContainersIndex = 0; sortedContainersIndex < sortedContainers.length;) {
let candidateContainer = sortedContainers[sortedContainersIndex];
let contentCount = contentFn(candidateContainer).length;
if (divisionBucket.count + contentCount > targetContentPerDivision) {
sortedContainersIndex++;
continue;
}
divisionBucket.count += contentCount;
divisionBucket.containers.push(candidateContainer);
sortedContainers.splice(sortedContainersIndex, 1);
}
}
return Lazy(divisionBuckets).map((bucket) => { return bucket.containers; }).toArray();
}
}
exports.EvenDistributor = EvenDistributor;