Skip to content

Commit

Permalink
🐝 (svg-tester) move cartesian function to utils
Browse files Browse the repository at this point in the history
  • Loading branch information
sophiamersmann committed Jan 22, 2024
1 parent 6296392 commit 4fb6126
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 9 deletions.
10 changes: 1 addition & 9 deletions devTools/svgTester/chart-configurations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
FacetStrategy,
GrapherQueryParams,
} from "@ourworldindata/grapher"
import { cartesian } from "@ourworldindata/utils"

export type ViewMatrix = Record<keyof GrapherQueryParams, string[]>

Expand Down Expand Up @@ -147,15 +148,6 @@ export const queryStringsByChartType = Object.fromEntries(
})
) as Record<ChartTypeName, string[]>

// adapted from https://stackoverflow.com/questions/12303989/cartesian-product-of-multiple-arrays-in-javascript
function cartesian(matrix: any[][]) {
if (matrix.length === 0) return []
if (matrix.length === 1) return matrix[0].map((i) => [i])
return matrix.reduce((acc, curr) =>
acc.flatMap((i: any) => curr.map((j: any) => [i, j].flat()))
)
}

function toQueryStr(params: Record<string, string>): string {
return new URLSearchParams(params).toString()
}
Expand Down
45 changes: 45 additions & 0 deletions packages/@ourworldindata/utils/src/Util.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
greatestCommonDivisor,
findGreatestCommonDivisorOfArray,
traverseEnrichedBlocks,
cartesian,
} from "./Util.js"
import {
BlockImageSize,
Expand Down Expand Up @@ -747,3 +748,47 @@ describe(traverseEnrichedBlocks, () => {
])
})
})

describe(cartesian, () => {
it("returns an empty list when no arrays are provided", () => {
expect(cartesian([])).toEqual([])
})

it("returns individual items if a single array is given", () => {
expect(cartesian([["a", "b"]])).toEqual([["a"], ["b"]])
})

it("returns all possible combinations if multiple arrays are given", () => {
expect(cartesian([["a", "b"], ["x"]])).toEqual([
["a", "x"],
["b", "x"],
])
expect(
cartesian([
["a", "b"],
["x", "y"],
])
).toEqual([
["a", "x"],
["a", "y"],
["b", "x"],
["b", "y"],
])
expect(
cartesian([
["a", "b"],
["x", "y"],
["+", "-"],
])
).toEqual([
["a", "x", "+"],
["a", "x", "-"],
["a", "y", "+"],
["a", "y", "-"],
["b", "x", "+"],
["b", "x", "-"],
["b", "y", "+"],
["b", "y", "-"],
])
})
})
14 changes: 14 additions & 0 deletions packages/@ourworldindata/utils/src/Util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1783,3 +1783,17 @@ export function checkIsDataInsight(
const type = get(x, "content.type")
return type === OwidGdocType.DataInsight
}

/**
* Returns the cartesian product of the given arrays.
*
* For example, `cartesian([["a", "b"], ["x", "y"]])` returns `[["a", "x"], ["a", "y"], ["b", "x"], ["b", "y"]]`
*/
export function cartesian<T>(matrix: T[][]): T[][] {
if (matrix.length === 0) return []
if (matrix.length === 1) return matrix[0].map((i) => [i])
return matrix.reduce<T[][]>(
(acc, curr) => acc.flatMap((i) => curr.map((j) => [...i, j])),
[[]]
)
}
1 change: 1 addition & 0 deletions packages/@ourworldindata/utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ export {
copyToClipboard,
checkIsGdocPost,
checkIsDataInsight,
cartesian,
} from "./Util.js"

export {
Expand Down

0 comments on commit 4fb6126

Please sign in to comment.