gpt4 book ai didi

javascript - 将动态字符串转换为 JavaScript 中的逻辑表达式

转载 作者:行者123 更新时间:2023-12-01 01:00:06 25 4
gpt4 key购买 nike

这可能有点困难,因为除了标准运算符之外,我还没有看到任何人尝试过这一点。

我有一个包含大约 50k 行对象的表,每行需要针对它们运行一组“最多 30”个表达式并返回 true 或 false。我已经成功地与大量固定运营商完成了这项工作,但它很快就会变得困惑。

有人有更好的方法吗?下面的最小代码 - 问题出在验证函数中。


const objects = [
{
'First Name': 'Chris',
'Age': 18,
'Major': 'Mathematics',
'College Department': 'Mathematics'
},
{
'First Name': 'null',
'Age': 21,
'Major': 'Mathematics',
'College Department': 'Science'
}
]

const validate = (object, rule) => {
// logic to convert rule to logical expression
}

const results = objects.map(object => {
var flags = []
flags.push(validate(object, '[Fist Name] is null'))
flags.push(validate(object, '[Age] < [Required Age]'))
flags.push(validate(object, '[Major] === [College Department] and [Age] > [Required Age]'))
// Validate is supposed to return
// {Rule: '[Fist Name] is null', Flag: false/true, ...Rest of original object and key pairs}

// ... Return array of flags
return flags;
})

// Result should look like this
// lets say required age is 18
[
[
{Rule: '[Fist Name] is null', Flag: false, 'First Name': 'Chris', 'Age': 18, 'Major': 'Mathematics', 'College Department': 'Mathematics'},
{Rule: '[Age] < [Required Age]', Flag: false, 'First Name': 'Chris', 'Age': 18, 'Major': 'Mathematics', 'College Department': 'Mathematics'},
{Rule: '[Major] === [College Department] and [Age] > [Required Age]', Flag: true, 'First Name': 'Chris', 'Age': 18, 'Major': 'Mathematics', 'College Department': 'Mathematics'}
],
[
{Rule: '[Fist Name] is null', Flag: true, 'First Name': 'null', 'Age': 21, 'Major': 'Mathematics', 'College Department': 'Science'},
{Rule: '[Age] < [Required Age]', Flag: false, 'First Name': 'null', 'Age': 21, 'Major': 'Mathematics', 'College Department': 'Science'},
{Rule: '[Major] === [College Department] and [Age] > [Required Age]', Flag: false, 'First Name': 'null', 'Age': 21, 'Major': 'Mathematics', 'College Department': 'Science'}
]
]

// I know how to concat the arrays into one,
// so either the above output works or the one below works
[
{Rule: '[Fist Name] is null', Flag: false, 'First Name': 'Chris', 'Age': 18, 'Major': 'Mathematics', 'College Department': 'Mathematics'},
{Rule: '[Age] < [Required Age]', Flag: false, 'First Name': 'Chris', 'Age': 18, 'Major': 'Mathematics', 'College Department': 'Mathematics'},
{Rule: '[Major] === [College Department] and [Age] > [Required Age]', Flag: true, 'First Name': 'Chris', 'Age': 18, 'Major': 'Mathematics', 'College Department': 'Mathematics'},
{Rule: '[Fist Name] is null', Flag: true, 'First Name': 'null', 'Age': 21, 'Major': 'Mathematics', 'College Department': 'Science'},
{Rule: '[Age] < [Required Age]', Flag: false, 'First Name': 'null', 'Age': 21, 'Major': 'Mathematics', 'College Department': 'Science'},
{Rule: '[Major] === [College Department] and [Age] > [Required Age]', Flag: false, 'First Name': 'null', 'Age': 21, 'Major': 'Mathematics', 'College Department': 'Science'}
]

更新 这是我已经走了多远,但只能对 >、<=、> 执行此操作,或者至少这就是我迄今为止测试过的所有内容。我将很快添加更多详细说明的评论。


const object = {Age: 10, Required: 18};
const rules = [
{R: '["Age"] < ["Required"]', O: ['<']},
{R: '["Age"] <= ["Required"]', O: ['<=']},
{R: '["Age"] > ["Required"]', O: ['>']},
]

// Prototype that will parse the string
// ... then return the indexes of char
// ... we will use this to insert object name before the char
String.prototype.toIndices = function (d) { return this.split("").reduce((a, e, i) => e === d ? a.concat(i) : a, []) };

String.prototype.splice = function(idx, rem, str) {
return this.slice(0, idx) + str + this.slice(idx + Math.abs(rem));
};

Object.prototype.validateRule = function (r) {
const newString = r['R'].toIndices("[").map(s => {
return r['R'].splice(s, 0, 'object');
})

var exp = [];

for (let item = 0; item < newString.length; item++) {
for (let obj = 0; obj < newString[item].split(" ").length; obj++) {
if (newString[item].split(" ")[obj].includes("object"))
exp.push(newString[item].split(" ")[obj])
}
}

return [...exp].map((e, i) => i < exp.length - 1 ? [e, r['O'][0]] : [e]).reduce((a, b) => a.concat(b)).join(" ");
}


console.log({Rule: rules[0]['R'], Flag: eval(object.validateRule(rules[0]))});
// output
/*
{ Rule: '["Age"] < ["Required"]', Flag: true }
*/

console.log(rules.map(rule => { return {Rule: rule['R'], Flag: eval(object.validateRule(rule))} }));
// output
/*
[ { Rule: '["Age"] < ["Required"]', Flag: true },
{ Rule: '["Age"] <= ["Required"]', Flag: true },
{ Rule: '["Age"] > ["Required"]', Flag: false } ]
*/

最佳答案

如果您需要计算的表达式提前已知,请用代码写出表达式。

const rules = new Map()
rules.set("[First Name] is null", function(object) {
return object.firstName === null
})

创建自己的迷你语言需要大量工作。如果您需要让用户添加自定义规则,那么构建规则解析器和评估引擎是有意义的。

<小时/>

在解析代码中,计算表达式的方法通常是将输入分解为标记,然后在第二步中计算标记。

function parse(textInput) {
return arrayOfTokens
}

文本输入示例:[拳头名称]为空

token 数组示例:[ new Field("First Name"), new OpIsNull() ]

为不同的文本输入编写大量单元测试,并确保它返回预期的标记。当解析正常工作时,下一步是评估标记。为标记、对象和预期输出值的数组编写大量单元测试。

function evaluate(object, tokens) {
let leftHand = null
if (tokens[0] instanceof Field) {
leftHand = getFieldValue(object, tokens[0])
}
if (tokens[1] instanceof OpIsNull) {
return leftHand === null
}
// etc
}

function getFieldValue(object, field) {
if (field.name == "First Name") {
return object.firstName
}
}

关于javascript - 将动态字符串转换为 JavaScript 中的逻辑表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56160045/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com