繁体   English   中英

Javascript 将 Json 转换为数组字符串格式

[英]Javascript convert Json to an array string format

我想将 json 转换为字符串“过滤器”格式,反之亦然。

Json 格式

{
  "condition": "and",
  "rules": [
    {
      "field": "Name",
      "operator": "=",
      "value": "Jack"
    },
    {
      "field": "UserId",
      "operator": "=",
      "value": 2
    },
    {
      "field": "Surname",
      "operator": "=",
      "value": "Rose"
    },
    {
      "condition": "or",
      "rules": [
        {
          "field": "Code",
          "operator": "=",
          "value": "X"
        },
        {
          "field": "Type",
          "operator": "=",
          "value": "Z"
        }
      ]
    }
  ]
};

字符串过滤器格式

[
  ["Name","=", "Jack"],
  ["and"],
  ["UserId", "=", 2],
  ["and"],
  ["Surname","=", "Rose"]
,
["and"],
(
["Code","=","X"],
["or"],
["Type","=","Z"]
)
]

目前,我有以下 js 代码,它输出了一半的内容,但我缺少需要在各个字段之间以及“(”“)”括号之间的“and”和“or”条件周围对字段进行分组。

我需要能够从 json 转换为“过滤器”格式,然后再转换回来。

这是我到目前为止的代码:在这种情况下,查询是我在上面发布的 json。

 const query={condition:"and",rules:[{field:"Name",operator:"=",value:"Jack"},{field:"UserId",operator:"=",value:2},{field:"Surname",operator:"=",value:"Rose"},{condition:"or",rules:[{field:"Code",operator:"=",value:"X"},{field:"Type",operator:"=",value:"Z"}]}]}; const parseRule = (rule) => { if (rule.rules) { return rule.rules.map(r=> parseRule(r)); } return [rule.field, rule.operator, rule.value]; }; let filterFormat = parseRule(query); console.log(filterFormat);

我被困在这里。 我几乎需要类似数组的连接,其中条件可以作为数组添加到其他数组之间,而不会像使用普通连接那样丢失数组。

我认为您已经成功的部分是从规则对象树到嵌套数组格式。 我使用 3 个主要函数编写它:

  • childToArray只检查节点是condition还是rule并转发到正确的解析器函数
  • ruleToArray获取对象并将其转换为类似元组的数组
  • conditionToArray映射所有嵌套的子项并将它们与operator交织在一起

对于交织,我使用了一种实用方法,它基本上可以做到这一点:

  (a, [1, 2, 3]) -> [1, a, 2, a, 3]
const childToArray = child => "condition" in child 
  ? conditionToArray(child)
  : ruleToArray(child);

const ruleToArray = ({ field, operator, value }) => [field, operator, value];
const conditionToArray = ({ condition, rules }) =>
  interweave(
    [ condition ],
    rules.map(childToArray)
  )

这种数组格式可能与您的要求略有不同,但它是“无损的”,这意味着我们可以将其转换回树状对象!

类似的方法:

  • 检查数组是否代表rule (值将是字符串)或condition (值将是数组)
  • 如果是规则,则将元组转换为具有命名键的对象
  • 如果是条件,则提取condition并解析嵌套数组

为了解开我们的[1, a, 2, a, 3]类型数组,我编写了一个实用程序,它可以:

([1, a, 2, a, 3]) -> [ a, [ 1, 2, 3] ]
const buildTree = arr => {
  const isCondition = Array.isArray(arr[0]);
  
  return isCondition
    ? conditionToObject(untangle(arr))
    : ruleToObject(arr);
}

const conditionToObject = ([ [ condition ], children ]) => ({
  condition,
  rules: children.map(buildTree)
});
const ruleToObject = ([ field, operator, value ]) => ({
  field, operator, value
});

将它们与您的测试数据放在一起:

 // Transforming object trees to nested arrays const childToArray = child => "condition" in child ? conditionToArray(child) : ruleToArray(child); const ruleToArray = ({ field, operator, value }) => [field, operator, value] const conditionToArray = ({ condition, rules }) => interweave( [ condition ], rules.map(childToArray) ) // Transforming nested arrays to object trees const buildTree = arr => { const isCondition = Array.isArray(arr[0]); return isCondition ? conditionToObject(untangle(arr)) : ruleToObject(arr); } const conditionToObject = ([ [ condition ], children ]) => ({ condition, rules: children.map(buildTree) }); const ruleToObject = ([ field, operator, value ]) => ({ field, operator, value }); // App: // 1) To array const arrayOutput = childToArray(getInput()); // 2) Back to object const objectOutput = buildTree(arrayOutput); // 3) Log output console.log("Array output"); console.log(JSON.stringify(arrayOutput)); console.log("Object output"); console.log(objectOutput); // 4) Verify equality console.log( "inp obj -> arr -> out obj == inp obj:", JSON.stringify(objectOutput) === JSON.stringify(getInput()) ); // 5) arrayOutput with custom toString const arrayOutputToString = arr => { const isCond = Array.isArray(arr[0]); return isCond ? `(${arr.map(arrayOutputToString)})` : JSON.stringify(arr) } console.log( arrayOutputToString(arrayOutput) ) function getInput() { return { "condition": "and", "rules": [{ "field": "Name", "operator": "=", "value": "Jack" }, { "field": "UserId", "operator": "=", "value": 2 }, { "field": "Surname", "operator": "=", "value": "Rose" }, { "condition": "or", "rules": [{ "field": "Code", "operator": "=", "value": "X" }, { "field": "Type", "operator": "=", "value": "Z" } ] } ] } };
 <script> // Utils const interweave = (y, xs) => xs.flatMap( (x, i) => i === xs.length - 1 ? [x] : [x, y] ); const untangle = xs => { const wovenEl = xs[1]; const els = []; for (let i = 0; i < xs.length; i += 2) { els.push(xs[i]); } return [ wovenEl, els ]; } </script>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM