Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/426.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 树结构的转换_Javascript_Algorithm - Fatal编程技术网

Javascript 树结构的转换

Javascript 树结构的转换,javascript,algorithm,Javascript,Algorithm,我正在为我的QueryBuilderJavaScript库()解决一个问题 目标是从SQL语句填充生成器。为此,我使用WHERE子句转换为AST 现在我的问题是,我需要将这个AST(一种二叉树)转换为QueryBuilder的内部格式(我不知道技术名称)。但我很笨,找不到一个有效的算法 所以我来这里找一个擅长这个的人!我只需要主算法来转换数据结构,转换值和运算符格式不会有问题 注: 深度不受限制 组条件(当然)仅为和或 虽然规则的顺序并不重要,但应该予以保留 输入SQL为(测试用例): 我想

我正在为我的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)