[英]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.