Skip to content

Commit

Permalink
Merge pull request #3480 from owid/search-utils
Browse files Browse the repository at this point in the history
enhance(search): Search utils
  • Loading branch information
marcelgerber authored Apr 11, 2024
2 parents f364c91 + 41bbdcc commit cca1779
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 1 deletion.
2 changes: 2 additions & 0 deletions packages/@ourworldindata/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export {
isTouchDevice,
type Json,
csvEscape,
escapeRegExp,
urlToSlug,
trimObject,
fetchText,
Expand Down Expand Up @@ -240,6 +241,7 @@ export {
countries,
type Country,
getCountryBySlug,
getRegionByNameOrVariantName,
isCountryName,
continents,
type Continent,
Expand Down
33 changes: 32 additions & 1 deletion packages/@ourworldindata/utils/src/regions.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#! /usr/bin/env jest

import { isCountryName, getCountryBySlug } from "./regions.js"
import {
isCountryName,
getCountryBySlug,
getRegionByNameOrVariantName,
} from "./regions.js"

it("isCountryName", () => {
expect(isCountryName("United States")).toEqual(true)
Expand All @@ -15,3 +19,30 @@ it("getCountryBySlug", () => {
})
expect(getCountryBySlug("not-a-country")).toEqual(undefined)
})

it("getRegionByNameOrVariantName", () => {
expect(getRegionByNameOrVariantName("United States")).toMatchObject({
name: "United States",
slug: "united-states",
code: "USA",
})

expect(getRegionByNameOrVariantName("USA")).toMatchObject({
name: "United States",
slug: "united-states",
code: "USA",
})

// Test case-insensitivity
expect(getRegionByNameOrVariantName("UNITED KINGDOM")).toMatchObject({
name: "United Kingdom",
slug: "united-kingdom",
code: "GBR",
})

expect(getRegionByNameOrVariantName("uae")).toMatchObject({
name: "United Arab Emirates",
slug: "united-arab-emirates",
code: "ARE",
})
})
17 changes: 17 additions & 0 deletions packages/@ourworldindata/utils/src/regions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,18 @@ const countriesBySlug: Record<string, Country> = Object.fromEntries(
countries.map((country) => [country.slug, country])
)

const regionsByNameOrVariantNameLowercase: Map<string, Region> = new Map(
regions.flatMap((region) => {
const names = [region.name.toLowerCase()]
if ("variantNames" in region && region.variantNames) {
names.push(
...region.variantNames.map((variant) => variant.toLowerCase())
)
}
return names.map((name) => [name, region])
})
)

const currentAndHistoricalCountryNames = regions
.filter(({ regionType }) => regionType === "country")
.map(({ name }) => name.toLowerCase())
Expand All @@ -76,3 +88,8 @@ export const isCountryName = (name: string): boolean =>

export const getCountryBySlug = (slug: string): Country | undefined =>
countriesBySlug[slug]

export const getRegionByNameOrVariantName = (
nameOrVariantName: string
): Region | undefined =>
regionsByNameOrVariantNameLowercase.get(nameOrVariantName.toLowerCase())
24 changes: 24 additions & 0 deletions site/search/SearchUtils.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import {
Region,
getRegionByNameOrVariantName,
regions,
escapeRegExp,
} from "@ourworldindata/utils"

const allCountryNamesAndVariants = regions.flatMap((c) => [
c.name,
...(("variantNames" in c && c.variantNames) || []),
])

// A RegExp that matches any country, region and variant name. Case-independent.
const regionNameRegex = new RegExp(
`\\b(${allCountryNamesAndVariants.map(escapeRegExp).join("|")})\\b`,
"gi"
)

export const extractRegionNamesFromSearchQuery = (query: string) => {
const matches = query.matchAll(regionNameRegex)
const regionNames = Array.from(matches, (match) => match[0])
if (regionNames.length === 0) return null
return regionNames.map(getRegionByNameOrVariantName) as Region[]
}

0 comments on commit cca1779

Please sign in to comment.