Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance Path Uniqueness Logic in Search Component #175

Merged
merged 1 commit into from
Dec 21, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading