compare-lists
Version:
Super efficiently compares two sorted lists (arrays, strings, anything that is iterable actually).
91 lines (90 loc) • 3.09 kB
JavaScript
;
exports.__esModule = true;
/**
* Efficiently compares two lists (arrays, strings, Maps, etc - anything that implements the iterable protocol).
* Both iterables must have their values presorted in ascending order or the function will behave unexpectedly.
*/
function compareLists(options) {
var leftIterator = options.left[Symbol.iterator]();
var rightIterator = options.right[Symbol.iterator]();
var compare = options.compare, returnReport = options.returnReport, onMissingInLeft = options.onMissingInLeft, onMissingInRight = options.onMissingInRight, onMatch = options.onMatch;
var result = compareIterators({
left: leftIterator,
right: rightIterator,
compare: compare,
returnReport: returnReport || undefined,
onMatch: onMatch,
onMissingInLeft: onMissingInLeft,
onMissingInRight: onMissingInRight
});
return result;
}
exports.compareLists = compareLists;
/**
* Efficiently compares two lists (arrays, strings, Maps, etc - anything that implements the iterable protocol).
* Both iterables must have their values presorted in ascending order or the function will behave unexpectedly.
*/
function compareIterators(options) {
var leftIterator = options.left;
var rightIterator = options.right;
var compare = options.compare, onMissingInLeft = options.onMissingInLeft, onMissingInRight = options.onMissingInRight, onMatch = options.onMatch, returnReport = options.returnReport;
var result = returnReport
? {
missingInLeft: [],
missingInRight: [],
matches: []
}
: undefined;
var left;
var right;
var nextLeft = function () { return (left = leftIterator.next()); };
var nextRight = function () { return (right = rightIterator.next()); };
var handleMissingInLeft = function () {
if (returnReport) {
result.missingInLeft.push(right.value);
}
if (onMissingInLeft) {
onMissingInLeft(right.value);
}
nextRight();
};
var handleMissingInRight = function () {
if (returnReport) {
result.missingInRight.push(left.value);
}
if (onMissingInRight) {
onMissingInRight(left.value);
}
nextLeft();
};
var handleMatch = function () {
if (returnReport) {
result.matches.push([left.value, right.value]);
}
if (onMatch) {
onMatch(left.value, right.value);
}
nextLeft();
nextRight();
};
nextLeft();
nextRight();
while (!left.done || !right.done) {
var compareResult = left.done
? 1
: right.done
? -1
: compare(left.value, right.value);
if (compareResult < 0) {
handleMissingInRight();
}
else if (compareResult > 0) {
handleMissingInLeft();
}
else {
handleMatch();
}
}
return result;
}
exports.compareIterators = compareIterators;