I have a key/value map of paths that have changed that looks like this example:
{
'/A' => '/AA',
'/A/B' => '/AA/B',
'/A/C' => '/AA/C',
'/A/D' => '/AA/D'
}
The left value is the old path, the right value is the new path.
I need to reduce this to just the paths that have changed and filter out the redundant non-changed children. For example, if I change '/A' to '/AA' then I don't need the children, unless they have been changed, etc.
The rub is these paths can be quite deep and I need to somehow recursively end up with just what has actually changed.
3 days no luck, can't get my head around it, thanks mighty code warriors for any help :)
Just iterate them and remove everything for which a matching ancestor move exists:
const moves = new Map([
['/A', '/AA'],
['/A/B', '/AA/B'],
['/A/C', '/AA/C'],
['/A/D', '/AA/X'],
]);
for (const [from, to] of moves) {
const fromParts = from.split('/');
for (let i=1; i<fromParts.length; i++) {
const parentFrom = fromParts.slice(0, i).join('/');
const parentTo = moves.get(parentFrom);
if (parentTo !== undefined) {
const sub = '/' + fromParts.slice(i).join('/');
if (parentTo + sub === to) {
console.log(`Move ${from}=>${to} contained in move ${parentFrom}=>${parentTo}`);
moves.delete(from);
} else {
console.log(`Source ${from} is part of ${parentFrom}, but ${sub} was moved to ${to} instead of ${parentTo + sub}`);
}
}
}
}
console.log(Object.fromEntries(moves));
If you don't like to mutate the input moves map, you can also just use filter() on an array of moves; it just needs to be able to lookup potential parent moves.