簡體   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