To accomplish this task effortlessly, you can utilize the eval function, which executes a string as javascript.
Here is the basic logic:
- Create the different conditions as a javascript string (
is_child
, is_adult
, ...)
This function will replace all variables (represented as strings) with their corresponding values. To achieve this, you will need to build a dictionary listing all variables along with their values:
const varsToReplace = {
country: 'Norway',
age: 12
}
Next, replace these variables in a given condition using the replace method. A crucial point here is to search for
country
instead of just
country
(the extra space before and after prevents unintended replacements like
user_country
becoming
user_Norway
). Additionally, remember to enclose string replacements in
''
:
const getConditionString = (condition) => {
let replacedCondition = ` ${conditions[condition]} `
Object.keys(varsToReplace).forEach((variable) => {
const re = new RegExp(` ${variable} `, 'g');
let replaceValue = ` ${varsToReplace[variable]} `
// Wrap string values in ''
if (typeof varsToReplace[variable] === 'string') {
replaceValue = ` '${varsToReplace[variable]}' `
}
replacedCondition = replacedCondition.replace(re, replaceValue)
})
return replacedCondition
}
- Create the test as a javascript string (
is_child and is_scandinavian
, ...)
The getTestString
function replaces all condition keys with the corresponding javascript strings using the previous function:
const getTestString = (test) => {
let replacedTest = ` ${tests[test]} `
Object.keys(conditions).forEach((condition) => {
const re = new RegExp(` ${condition} `, 'g');
replacedTest = replacedTest.replace(re, ` ( ${getConditionString(condition)} ) `)
})
return replacedTest
}
- Convert the various operators to be 'js valid':
const replaceOperators = (string) => {
const operators = {
or: '||',
and: '&&'
}
Object.keys(operators).forEach((operator) => {
const re = new RegExp(` ${operator} `, 'g');
string = string.replace(re, ` ${operators[operator]} `)
})
return string
}
- Execute the javascript string using eval:
const evalTest = (test) => {
let testAsString = replaceOperators(getTestString(test))
return eval(testAsString)
}
Here is the full example:
const country = 'Norway'
const age = 12
const varsToReplace = {
country,
age
}
const conditions = {
"is_child": "age < 16",
"is_adult": "age >= 16 and age < 67",
"is_senior": "age > 67",
"is_scandinavian": "country == 'Norway' or country == 'Sweden' or country == 'Denmark'"
}
const tests = {
"childTicket": "is_child and is_scandinavian",
"flexTicket": "is_scandinavian and ( is_adult or is_senior )"
}
const getConditionString = (condition) => {
let replacedCondition = ` ${conditions[condition]} `
Object.keys(varsToReplace).forEach((variable) => {
const re = new RegExp(` ${variable} `, 'g');
let replaceValue = ` ${varsToReplace[variable]} `
if (typeof varsToReplace[variable] === 'string') {
replaceValue = ` '${varsToReplace[variable]}' `
}
replacedCondition = replacedCondition.replace(re, replaceValue)
})
return replacedCondition
}
const getTestString = (test) => {
let replacedTest = ` ${tests[test]} `
Object.keys(conditions).forEach((condition) => {
const re = new RegExp(` ${condition} `, 'g');
replacedTest = replacedTest.replace(re, ` ( ${getConditionString(condition)} ) `)
})
return replacedTest
}
const replaceOperators = (string) => {
const operators = {
or: '||',
and: '&&'
}
Object.keys(operators).forEach((operator) => {
const re = new RegExp(` ${operator} `, 'g');
string = string.replace(re, ` ${operators[operator]} `)
})
return string
}
const evalTest = (test) => {
let testAsString = replaceOperators(getTestString(test))
console.log(testAsString)
return eval(testAsString)
}
console.log(evalTest('childTicket'))
console.log(evalTest('flexTicket'))