Skip to content

Commit

Permalink
back: Enhance Unique Path Calculation in Search Component.
Browse files Browse the repository at this point in the history
Refactored the formatNames function in Search.jsx to handle cases where regions
with the same name appear under different parent regions or within nested
structures. The updated logic includes grouping paths by the last element
(region name), finding the common prefix for each group of paths, and then
determining the shortest unique suffix for each region. This approach ensures
that each region is uniquely identifiable, especially in scenarios where
regions share the same name.

Issue: #172

Signed-off-by: Nikolay Martyanov <[email protected]>
  • Loading branch information
OhmSpectator committed Dec 21, 2023
1 parent 0412573 commit 77d3f1f
Showing 1 changed file with 36 additions and 25 deletions.
61 changes: 36 additions & 25 deletions frontend/src/components/Search.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,38 +11,49 @@ function Search() {
const { selectedRegion, setSelectedRegion, selectedHierarchyId } = useNavigation();
const prevSelectedRegion = useRef();

// Returns an object of the form:
// { name: 'Region Name', segment: 'Region Segment (if name is not unique)', id: 'Region ID' }
function formatNames(foundResults) {
const nameCount = new Map();
foundResults.forEach((item) => {
nameCount.set(item.name, (nameCount.get(item.name) || 0) + 1);
});

return foundResults.map((item) => {
if (nameCount.get(item.name) === 1) {
return ({
name: item.name,
segment: null,
id: item.id,
}); // Unique name, return as is
// Group paths by the last element (which is the same as region.name)
const pathsByLastName = {};
foundResults.forEach((region) => {
if (!pathsByLastName[region.name]) {
pathsByLastName[region.name] = [];
}
// Find the smallest unique path segment
const pathSegments = item.path.split(' > ');
let uniqueSegment = pathSegments[pathSegments.length - 1];
pathsByLastName[region.name].push(region.path);
});

for (let i = pathSegments.length - 2; i >= 0; i -= 1) {
const testPath = pathSegments.slice(i).join(' > ');
const isUnique = foundResults.filter((r) => r.path.includes(testPath)).length === 1;
if (isUnique) {
uniqueSegment = pathSegments.slice(i).join(' > ');
// Find the common prefix of each group of paths
function findCommonPrefixByTokens(paths) {
const tokens = paths.map((path) => path.split(' > '));
const minLength = Math.min(...tokens.map((token) => token.length));
let prefix = '';
for (let i = 0; i < minLength; i += 1) {
const token = tokens[0][i];
if (tokens.every((t) => t[i] === token)) {
prefix += `${token} > `;
} else {
break;
}
}
return prefix;
}

return ({
name: item.name,
segment: uniqueSegment,
id: item.id,
});
// Process each group to find the shortest unique suffix
return foundResults.map((region) => {
const paths = pathsByLastName[region.name];
if (paths.length === 1) {
// Only one path with this name, no need to shorten
return { name: region.name, segment: null, id: region.id };
}
// Find the shortest unique suffix for this path
const prefix = findCommonPrefixByTokens(paths);
// Replace " >" with ","
return {
name: region.name,
segment: region.path.slice(prefix.length).replace(/ > /g, ', ').trim(','),
id: region.id,
};
});
}

Expand Down

0 comments on commit 77d3f1f

Please sign in to comment.