[英]Javascript convert Json to an array string format
我想将 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.