Skip to content

Commit 03ad22f

Browse files
committed
feat(expr): Make intersects() return the intersection when non-empty
1 parent 161b86c commit 03ad22f

File tree

2 files changed

+32
-5
lines changed

2 files changed

+32
-5
lines changed

src/schema/expressionLanguage.test.ts

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,27 @@ Deno.test('test expression functions', async (t) => {
1616
})
1717
await t.step('intersects function', () => {
1818
const intersects = expressionFunctions.intersects
19-
assert(intersects([1, 2, 3], [2, 3, 4]) === true)
19+
const equal = expressionFunctions.allequal
20+
21+
const truthy = (a: any): boolean => !!a
22+
23+
assert(truthy(intersects([1, 2, 3], [2, 3, 4])))
2024
assert(intersects([1, 2, 3], [4, 5, 6]) === false)
21-
assert(intersects(['abc', 'def'], ['def']) === true)
25+
assert(truthy(intersects(['abc', 'def'], ['def'])))
2226
assert(intersects(['abc', 'def'], ['ghi']) === false)
27+
// Just checking values, I'm not concerned about types here
28+
// @ts-expect-error
29+
assert(equal(intersects([1, 2, 3], [2, 3, 4]), [2, 3]))
30+
// @ts-expect-error
31+
assert(equal(intersects(['abc', 'def'], ['def']), ['def']))
2332

2433
// Promote scalars to arrays
2534
// @ts-ignore
26-
assert(intersects('abc', ['abc', 'def']) === true)
35+
assert(truthy(intersects('abc', ['abc', 'def'])))
2736
// @ts-ignore
2837
assert(intersects('abc', ['a', 'b', 'c']) === false)
38+
// @ts-expect-error
39+
assert(equal(intersects('abc', ['abc', 'def']), ['abc']))
2940
})
3041
await t.step('match function', () => {
3142
const match = expressionFunctions.match

src/schema/expressionLanguage.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,30 @@ export const expressionFunctions = {
4040
const index = list.indexOf(item)
4141
return index != -1 ? index : null
4242
},
43-
intersects: <T>(a: T[], b: T[]): boolean => {
43+
intersects: <T>(a: T[], b: T[]): T[] | boolean => {
44+
// Tolerate single values
4445
if (!Array.isArray(a)) {
4546
a = [a]
4647
}
4748
if (!Array.isArray(b)) {
4849
b = [b]
4950
}
50-
return a.some((x) => b.includes(x))
51+
// Construct a set from the smaller list
52+
if (a.length < b.length) {
53+
const tmp = a
54+
a = b
55+
b = tmp
56+
}
57+
if (b.length === 0) {
58+
return false
59+
}
60+
61+
const bSet = new Set(b)
62+
const intersection = a.filter((x) => bSet.has(x))
63+
if (intersection.length === 0) {
64+
return false
65+
}
66+
return intersection
5167
},
5268
match: (target: string, regex: string): boolean => {
5369
const re = RegExp(regex)

0 commit comments

Comments
 (0)