Javascript - 通过迭代/递归从另一个对象创建对象

时间:2018-03-27 10:16:32

标签: javascript recursion

我拥有的对象就是这样。

[
    [
        ["first_name", "==", "tom"], "||", ["first_name", "==", "harry"]
    ], "&&", ["gender", "==", "m"]
]

我想从上面构建的对象是:

{
  "condition": "&&",
  "rules": [
    {
      "field": "gender",
      "operator": "==",
      "value": "m"
    },
    {
      "condition": "||",
      "rules": [
        {
         "field": "first_name",
          "operator": "==",
          "value": "tom"
        },
        {
          "field": "first_name",
          "operator": "==",
          "value": "harry"
        }
      ]
    }
  ]
}

我尝试了什么?

现在感觉这么复杂,我甚至无法想出一个初步的概念。在我看来,递归函数调用将是一个良好的开端。

我想要实现的目标是什么?

我在对象中有这些规则,我想将它们转换为Query Builder规则。

这可以通过迭代/递归完成而不实际使用词法分析器和解析器吗?如果是的话,你会怎么做?浏览器JS解决方案只是请。

请注意

对象可以是n级深度,因此解决方案必须能够考虑到这一点。

3 个答案:

答案 0 :(得分:1)

var example = [
  [
    ["first_name", "==", "tom"], "||", ["first_name", "==", "harry"]
  ], 
  "&&", 
  ["gender", "==", "m"]
]

function recursion(array) {
  var result = {};
  if (array[1] !== '==') {
    result.condition = array[1];
    result.rules = [recursion(array[0]), recursion(array[2])];
  } else {
    result.field = array[0];
    result.operator = array[1];
    result.value = array[2];
  }

  return result;
}

console.log(recursion(example));

也许这会让你觉得好吗?您的原因必须添加一些检查,因为此函数需要数组看起来与您的示例完全相同,如果输入是意外的,则会失败。

答案 1 :(得分:1)

已经测试过这个解决方案并且它按预期工作,但您必须处理故障情况。希望它可以帮到你。

var arr = [
    [
        ["first_name", "==", "tom"],
        "||",
        ["first_name", "==", "harry"]
    ],
    "&&",
    ["gender", "==", "m"]
];

function processArray(arr) {
    if (Array.isArray(arr[0])) {
        return {
            condition: arr[1],
            rules: [processArray(arr[0]), processArray(arr[2])]
        };
    } else {
        return {
            field: arr[0],
            operator: arr[1],
            value: arr[2]
        }
    }
}

答案 2 :(得分:1)

你可以使用一个简单的递归函数,它通过让两个数组成为一个条件类型对象而另一个带有运算符的对象来返回。

function getObject(array) {
    return Array.isArray(array[0]) && Array.isArray(array[2])
        ? { condition: array[1], rules: [getObject(array[0]), getObject(array[2])] }
        : { field: array[0], operator: array[1], value: array[2] };
}

var data = [[["first_name", "==", "tom"], "||", ["first_name", "==", "harry"]], "&&", ["gender", "==", "m"]],
    result = getObject(data);
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }