conditionals
by jonahe
HTML
<pre id="condition"></pre>
<pre id="eval"></pre>
TypeScript
type NumericalOperator = ">" | ">=" | "==" | "<=" | "<" | "!=";
type LogicalOperator = "||" | "&&";
type FATLogicalOperator = "OR" | "AND";
const convertFATLogicalOperator = (
operator: FATLogicalOperator
): LogicalOperator => {
switch (operator) {
case "AND":
return "&&";
case "OR":
return "||";
default:
throw new Error(`Unsupported FAT logical operator: "${operator}"`);
}
};
type GeneralCondition = {
// X (subject) should be ...
subjectName: string;
numericalOperator: NumericalOperator;
logicalOperator: LogicalOperator;
// Eg. x is greater than $comparisonValue
comparisonValue: number;
};
//`(data[${targetName}] ${numericalOperator}) ${logicalOperator ?? "&& true"}`
const evaluateConditions = (
conditions: GeneralCondition[],
valuesBySubjectName: Record<string, number>
) => {
const evalString = conditions.reduce((acc, next, currentIndex, all) => {
const isLastCondition = currentIndex === all.length - 1;
if (!isLastCondition && !next.logicalOperator) {
throw new Error(
"Multiple numerical conditions need logical operator between them."
);
}
const actualValue = valuesBySubjectName[next.subjectName];
acc += `(${actualValue} ${next.numericalOperator} ${
next.comparisonValue
}) ${next.logicalOperator || ""}`;
return acc;
}, "");
return evalString;
};
const conditions = [{
subjectName: "score",
logicalOperator: "&&",
numericalOperator: ">=",
comparisonValue: 10
},
{
subjectName: "score",
//logicalOperator: "",
numericalOperator: "<=",
comparisonValue: 10
}
];
console.log(eval( evaluateConditions(conditions, { score: 10 }) ))