Javascript 树结构的转换
我正在为我的QueryBuilderJavaScript库()解决一个问题 目标是从SQL语句填充生成器。为此,我使用WHERE子句转换为AST 现在我的问题是,我需要将这个AST(一种二叉树)转换为QueryBuilder的内部格式(我不知道技术名称)。但我很笨,找不到一个有效的算法 所以我来这里找一个擅长这个的人!我只需要主算法来转换数据结构,转换值和运算符格式不会有问题 注:Javascript 树结构的转换,javascript,algorithm,Javascript,Algorithm,我正在为我的QueryBuilderJavaScript库()解决一个问题 目标是从SQL语句填充生成器。为此,我使用WHERE子句转换为AST 现在我的问题是,我需要将这个AST(一种二叉树)转换为QueryBuilder的内部格式(我不知道技术名称)。但我很笨,找不到一个有效的算法 所以我来这里找一个擅长这个的人!我只需要主算法来转换数据结构,转换值和运算符格式不会有问题 注: 深度不受限制 组条件(当然)仅为和或 虽然规则的顺序并不重要,但应该予以保留 输入SQL为(测试用例): 我想
- 深度不受限制
- 组条件(当然)仅为和或
- 虽然规则的顺序并不重要,但应该予以保留
我想我已经成功了,下面是伪代码:
var out = {
condition: null
rules: []
}
var curr = out
function flatten(node, level)
if node.operation = 'AND' or node.operation = 'OR' then
if level > 0 and curr.condition != node.operation then
curr.rules.push({
condition: null
rules: []
})
curr = curr.rules.end()
end if
curr.condition = node.operation
level++;
var next = curr
flatten(node.right, level)
curr = next
flatten(node.left, level)
else
curr.rules.push({
id: node.left.value
operator: node.operation
value: node.right.value
})
end if
end function
flatten(parsed, 0)
这是一个自调用的递归函数,当操作符在和和或之间变化时创建子组,而在展平左和右部分时在右子组中工作是一个小技巧
{
left: {
left: {
left: {
left: {
value: 'name'
},
operation: 'LIKE',
right: {
value: 'Mistic%'
},
},
operation: 'AND',
right: {
left: {
value: 'price'
},
operation: 'BETWEEN',
right: {
value: [
{
value: 100
},
{
value: 200
}
]
}
}
},
operation: 'AND',
right: {
left: {
left: {
value: 'category'
},
operation: 'IN',
right: {
value: [
{
value: 1
},
{
value: 2
}
]
}
},
operation: 'OR',
right: {
left: {
value: 'parent'
},
operation: '<=',
right: {
value: 0
}
}
}
},
operation: 'AND',
right: {
left: {
value: 'id'
},
operation: 'is not',
right: {
value: null
}
}
}
{
condition: 'AND',
rules: [
{
id: 'name',
operator: 'like',
value: 'Mistic%'
},
{
id: 'price',
operator: 'between',
value: [100, 200]
},
{
condition: 'OR',
rules: [
{
id: 'category',
operator: 'in',
value: [1, 2]
},
{
id: 'parent',
operator: 'less_or_equal',
value: 0
}
]
},
{
id: 'id',
operator: 'not_null',
value: null
}
]
}
var out = {
condition: null
rules: []
}
var curr = out
function flatten(node, level)
if node.operation = 'AND' or node.operation = 'OR' then
if level > 0 and curr.condition != node.operation then
curr.rules.push({
condition: null
rules: []
})
curr = curr.rules.end()
end if
curr.condition = node.operation
level++;
var next = curr
flatten(node.right, level)
curr = next
flatten(node.left, level)
else
curr.rules.push({
id: node.left.value
operator: node.operation
value: node.right.value
})
end if
end function
flatten(parsed, 0)