Route Wildcard Query
MediumTrie · Atlassian
You are writing the router for a web service. Each element of routes is [pattern, value], where pattern is a path such as "/users/*/repos". Each element of queries is a concrete request path such as "/users/42/repos". For each query, return the value of the route that handles it.
Segments. Split every path on / and ignore empty pieces, so "/a/b", "a/b" and "/a/b/" all have the segments ["a", "b"], and "/" has no segments at all.
Matching. A pattern matches a query when they have the same number of segments and, at every position, the pattern segment is either * (which matches any single query segment) or exactly equal to the query segment. A * never matches zero or several segments. Comparisons are case-sensitive.
Choosing between matches. When more than one pattern matches, prefer the most specific one: compare the matching patterns segment by segment from the left, and at the first position where one has a literal segment and the other has *, the literal one wins. (Two different matching patterns always differ at some position in exactly this way.) If the same pattern string appears more than once in routes, the later entry replaces the earlier one.
Return a list with one string per query: the chosen route's value, or "" if no route matches.
Example 1
- Input:
- routes = [["/users/*/repos", "user-repos"], ["/users/me/repos", "my-repos"], ["/users/*/*", "user-item"], ["/*/me/settings", "any-settings"]], queries = ["/users/me/repos", "/users/42/repos", "/users/me/settings", "/teams/me/settings", "/users/me"]
- Output:
- ["my-repos", "user-repos", "user-item", "any-settings", ""]
- Explanation
/users/me/reposmatches three patterns and the fully literal one is most specific./users/me/settingsmatches both/users/*/*and/*/me/settings; they first differ at segment one, whereusersis literal, souser-itemwins./users/mehas only two segments, so nothing matches.
Example 2
- Input:
- routes = [["/a/b/c", "x"], ["/a/*/d", "y"]], queries = ["/a/b/d", "/a/b/c"]
- Output:
- ["y", "x"]
- Explanation
- For
/a/b/d, the literalbbranch leads only toc, so the router must back up and try the*branch, which matches./a/b/cmatches the literal route exactly.
Example 3
- Input:
- routes = [["/", "home"], ["/docs/", "docs"]], queries = ["/", "/docs", "/docs/intro"]
- Output:
- ["home", "docs", ""]
- Explanation
/has no segments and matches the root route. The trailing slash on/docs/is ignored./docs/introhas two segments and no route has two.
Constraints
0 <= routes.length, queries.length <= 10^4- Every path has at most
10segments. - Segments contain letters, digits,
-and_; only patterns contain*, and only as a whole segment. - Route values are non-empty strings.