Files
Aislo/tools/est-test/native-row-match.js

58 lines
2.4 KiB
JavaScript

// Match repeated codes by their unique descriptions when both sets agree.
const EstRowMatch = (() => {
function identities(original, current, key) {
const signature = (row) => JSON.stringify([row.Name || "", row.Size || "", row.Unite || ""]);
const groups = (items) => {
const result = new Map();
items.forEach((row, index) => {
const id = key(row, index),
values = result.get(id) || [];
values.push({ index, signature: signature(row) });
result.set(id, values);
});
return result;
};
const oldGroups = groups(original),
newGroups = groups(current),
oldIds = [],
currentIds = [];
for (const id of new Set([...oldGroups.keys(), ...newGroups.keys()])) {
const oldValues = oldGroups.get(id) || [],
currentValues = newGroups.get(id) || [];
if (oldValues.length <= 1 && currentValues.length <= 1) {
const identity = JSON.stringify([id, "single"]);
if (oldValues.length) oldIds[oldValues[0].index] = identity;
if (currentValues.length) currentIds[currentValues[0].index] = identity;
continue;
}
const counts = (values) => {
const result = new Map();
for (const value of values)
result.set(value.signature, (result.get(value.signature) || 0) + 1);
return result;
};
const oldCounts = counts(oldValues),
currentCounts = counts(currentValues);
const unique = (value) =>
oldCounts.get(value.signature) === 1 && currentCounts.get(value.signature) === 1;
for (const value of oldValues.filter(unique))
oldIds[value.index] = JSON.stringify([id, "signature", value.signature]);
for (const value of currentValues.filter(unique))
currentIds[value.index] = JSON.stringify([id, "signature", value.signature]);
const changedCount = oldValues.length !== currentValues.length;
oldValues
.filter((value) => !unique(value))
.forEach((value, index) => {
oldIds[value.index] = JSON.stringify([id, changedCount ? "old" : "remaining", index]);
});
currentValues
.filter((value) => !unique(value))
.forEach((value, index) => {
currentIds[value.index] = JSON.stringify([id, changedCount ? "new" : "remaining", index]);
});
}
return { original: oldIds, current: currentIds };
}
return { identities };
})();