1

I'm new to Javascript. I have below Json data. Input

let data = {
        "filters": {
            "operator": "AND",
            "args": [
                {
                    "operator": "OR",
                    "args": [
                        {
                            "operator": "EQ",
                            "name": "consumer_id",
                            "args": [
                                "200"
                            ],
                            "type": "string"
                        },
                        {
                            "operator": "AND",
                            "args": [
                                {
                                    "operator": "RANGE",
                                    "name": "created_date",
                                    "args": [
                                        {"from":1},{"to":2}
                                    ],
                                    "type": "number"
                                },
                                {
                                    "operator": "EQ",
                                    "name": "state",
                                    "args": [
                                        "TN"
                                    ],
                                    "type": "string"
                                }
                            ]
                        }
                    ]
                },
                {
                    "operator": "GE",
                    "name": "Character",
                    "args": [
                        "H"
                    ],
                    "type": "string"
                }
            ]
    }

I'm trying to do create a new Json with the following changes.

  1. Replace the key name from name to column.
  2. When the operator "RANGE" is found, split it into 2 operators using LE and GE.

Expected Output

{
  "filters": {
    "operator": "AND",
    "args": [
      {
        "operator": "OR",
        "args": [
          {
            "operator": "EQ",
            "column": "consumer_id",
            "args": [
              "200"
            ],
            "type": "string"
          },
          {
            "operator": "AND",
            "args": [
              {
                "operator": "LE",
                "column": "created_date",
                "args": [
                  1
                ],
                "type": "number"
              },
              {
                "operator": "GE",
                "column": "created_date",
                "args": [
                  2
                ],
                "type": "number"
              },
              {
                "operator": "EQ",
                "column": "state",
                "args": [
                  "TN"
                ],
                "type": "string"
              }
            ]
          }
        ]
      },
      {
        "operator": "GE",
        "column": "character",
        "args": [
          "H"
        ],
        "type": "string"
      }
    ]
  }
}

My code:

data.filters.args.filter( item => {
    iterateObject(item);
});
function iterateObject(obj) {
    for(var prop in obj) {
      if(typeof(obj[prop]) === "object" ) {
        iterateObject(obj[prop]);
    } else {
       if (prop === "operator" && obj[prop] === "RANGE") {
           obj={
              "LE": {"operator": "LE",
               "column": obj.name,
                "args": [obj.args[0].from],
                "type": obj.type
             },
            "GE":{
                "operator": "GE",
                "column": obj.name,
                "args": [obj.args[1].to],
                "type": obj.type
             }
           }
           console.log(obj) // The object gets replaced here, but I don't know how to map with original Json( ie, to the variable data )
       }
       if (prop === "name" ) {
           prop="column"
       } 
    }
  }
}
console.log(JSON.stringify(data));

Question:

I'm able to successfully achieve the change 1 I tried multiple ways to achieve change 2, I could not. Please help

Vinoth Karthick
  • 905
  • 9
  • 27
  • 1
    There's no [JSON](https://www.json.org/json-en.html) in your question -> [What is the difference between JSON and Object Literal Notation?](https://stackoverflow.com/questions/2904131/what-is-the-difference-between-json-and-object-literal-notation) – Andreas Oct 19 '21 at 10:20
  • Updated the question to modify JSON to Object Literal Notation, – Vinoth Karthick Oct 19 '21 at 10:28

1 Answers1

1

This should do the trick:

  1. Check object for name property; if present, copy it to column property and delete obj.name
  2. Check for obj.operator === 'RANGE'; if true,
    1. Rename operator to AND
    2. Create and add the two new single-operation objects to args
    3. Delete column and type fields

Example

let data = {
  "filters": {
    "operator": "AND",
    "args": [
      {
        "operator": "OR",
        "args": [
          {
            "operator": "EQ",
            "name": "consumer_id",
             "args": [
               "200"
             ],
             "type": "string"
           },
           {
             "operator": "AND",
             "args": [
               {
                 "operator": "RANGE",
                 "name": "created_date",
                 "args": [
                   {"from":1},{"to":2}
                 ],
                 "type": "number"
               },
               {
                 "operator": "EQ",
                 "name": "state",
                 "args": [
                   "TN"
                 ],
                 "type": "string"
               }
             ]
           }
         ]
       },
       {
         "operator": "GE",
         "name": "Character",
         "args": [
           "H"
         ],
         "type": "string"
       }
     ]
   }
};


function modify(obj) {
  if (!obj) return;
  
  if (obj.name) {
    obj.column = obj.name
    delete obj.name;
  }
  
  if (obj.operator === 'RANGE') {    
    obj.operator = 'AND';
    obj.args = [
      {
        "operator": "GE",
        "column": obj.column,
        "args": [ obj.args[0].from ],
        "type": obj.type
      },
      {
        "operator": "LE",
        "column": obj.column,
        "args": [ obj.args[1].to ],
        "type": obj.type
      }
    ];
    
    delete obj.column;
    delete obj.type;
  }
  
  for (const arg of obj.args || []) {
    modify(arg);
  }
}


modify(data.filters);
console.log(JSON.stringify(data, null, 2));
majusebetter
  • 1,458
  • 1
  • 4
  • 13
  • It works, could you please explain 1) const arg of obj.args || [] 2) JSON.stringify(data, null, 2) => What does null and 2 refer here? – Vinoth Karthick Oct 19 '21 at 13:04
  • 1
    Sure. 1) I used `||` here, saying, that if the left side is *falsy* (in this case `null` or `undefined`), initialize with the right side (empty array). You could also write an `if` statement around the loop, e.g. `if (obj.args) { for ... }`. 2) second argument `null` means "no replacer function", third argument denotes the number of spaces to be used for indentation when pretty-printing the JSON: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify – majusebetter Oct 19 '21 at 15:29