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 }) ))