Skip to content

Commit

Permalink
Merge pull request #2189 from IDEMSInternational/refactor/data-pipe-s…
Browse files Browse the repository at this point in the history
…pec-filter-constants

Refactor/data pipe spec filter constants
  • Loading branch information
esmeetewinkel authored Feb 20, 2024
2 parents b56e73e + 7ffb880 commit c4b0b14
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 1 deletion.
7 changes: 7 additions & 0 deletions packages/shared/src/models/dataPipe/operators/filter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,11 @@ describe("Filter", () => {
const outputIDs = output.column("first_name").values;
expect(outputIDs).toEqual(["Ada"]);
});
it("Ignores context variables that do not appear in condition string", () => {
// Passing a function to evaluator would throw error if not ignored
const testDf = new DataFrame([{ first_name: "Ada", invalid: new Function() }]);
const output = new filter(testDf, ["first_name === 'Ada'"]).apply();
const outputIDs = output.column("first_name").values;
expect(outputIDs).toEqual(["Ada"]);
});
});
16 changes: 15 additions & 1 deletion packages/shared/src/models/dataPipe/operators/filter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ class FilterOperator extends BaseOperator {

public satisfiesFilters(row: any) {
const evaluator = new JSEvaluator();
evaluator.setGlobalContext({ constants: row });
return this.filterConditions.every((condition) => {
evaluator.setGlobalContext({ constants: this.generateEvaluatorConstants(condition, row) });
try {
/**
* row fields can be accessed both from global and local context, e.g.
Expand All @@ -39,6 +39,20 @@ class FilterOperator extends BaseOperator {
}
});
}

/**
* Create a list of all key-value pairs of row data whose keys appear within condition string
* This reduces the complexity of later JS evaluation
**/
private generateEvaluatorConstants(condition: string, row: Record<string, any>) {
const constants: Record<string, any> = {};
for (const [key, value] of Object.entries(row)) {
if (condition.includes(key)) {
constants[key] = value;
}
}
return constants;
}
}

class FilterAnyOperator extends FilterOperator {
Expand Down

0 comments on commit c4b0b14

Please sign in to comment.