58 lines
2.4 KiB
JavaScript
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 };
|
|
})();
|