Tips for sorting through a complex data structure in JavaScript

Consider having a complex nested JavaScript object, for example:

{
  "?xml": {
    "@version": "1.0",
    "@encoding": "UTF-8"
  },
  "Customer": {
    "@xmlns": "http://NamespaceTest.com/CustomerTypes",
    "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
    "Name": {
      "#text": "Name1"
    },
    "DeliveryAddress": {
      "Line1": {
        "@xmlns": "http://NamespaceTest.com/CommonTypes",
        "#text": "Line11"
      },
      "Line2": {
        "@xmlns": "http://NamespaceTest.com/CommonTypes",
        "#text": "Line21"
      }
    }
  }
}

I want to specify certain properties I wish to remove from the structure using an array, such as ["?xml", "@xmlns"], resulting in the output below:

{
  "Customer": {
    "@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance",
    "Name": {
      "#text": "Name1"
    },
    "DeliveryAddress": {
      "Line1": {
        "#text": "Line11"
      },
      "Line2": {
        "#text": "Line21"
      }
    }
  }
}

I'm aware of achieving this using JSON.stringify(), like so:

function replacer(key, value) {
  if (key === "?xml" || key === "@xmlns") {
    return undefined;
  }
  return value;
}

var filtered = JSON.parse( JSON.stringify( original, replacer ) );

However, I am looking for a method that can filter a data structure similar to JSON.stringify(), but returns an object instead of a string. Is there such a function available?

Answer ā„–1

Unfortunately, JavaScript does not come equipped with a built-in function to deeply filter nested data structures like how JSON.stringify() handles it with a replacer callback. However, fear not! It is fairly straightforward to create your own deep filtering method:

function customFilter (data, replacer) {
    // keep primitive values as they are
    if ( !(data instanceof Object) ) return data;

    // only process plain objects and arrays
    var prototype = Object.getPrototypeOf(data);
    if (prototype !== Object.prototype && prototype !== Array.prototype) return data;

    // clone and apply filter
    var clonedData = (prototype === Object.prototype ? {} : []);
    for (var property in data) {
        if (!data.hasOwnProperty(property)) continue;

        var filteredValue = replacer(property, data[property]);

        if (filteredValue === undefined) continue;
        if (filteredValue instanceof Object) filteredValue = customFilter(filteredValue, replacer);
        clonedData[property] = filteredValue;
    }
    return clonedData;
}

The recursive function provided above allows you to deeply clone any "JSON-like" data structure containing plain objects {}, arrays [], and basic data types like numbers, strings, and booleans. Just like JSON.stringify(), you can filter the structure using a similar replacer callback. For instance, given a JSON-like object 'original' from your example, you can create a filtered copy like this:

function myReplacer (key, value) {
    if(key === "?xml" || key === "@xmlns") return undefined;
    else return value;
}

var filteredCopy = customFilter(original, myReplacer);

Keep in mind that while this "deep clone" method is quite useful, it may not be flawless due to some corner cases:

  • This function only works on objects inheriting directly from Object or Array. Other types of objects, including primitives and objects of different types, are simply copied without cloning.

    In such scenarios, modifications made to mutable objects like Date instances will reflect across both the original and the clone. To avoid this issue, ensure proper handling within your replacer function.

  • Non-enumerable properties and those with non-standard descriptors may not be properly cloned by customFilter(). Additionally, self-referencing Objects can cause the customFilter() function to enter an infinite recursion loop.

  • To handle special cases, you might need to adjust your replacer logic accordingly. As demonstrated in various examples, dealing with symbols, undefined values, and shared references requires thoughtful consideration.

Despite these limitations, customFilter() provides a solid solution for filtering nested data structures in JavaScript. It's worth noting that most deep clone implementations face similar challenges when dealing with complex object structures and inheritance hierarchies.

Answer ā„–2

Presenting a solution to the problem:

var data = '{"?xml": {"@version": "1.0","@encoding": "UTF-8"},"Customer": {"@xmlns": "http://NamespaceTest.com/CustomerTypes","@xmlns:xsi": "http://www.w3.org/2001/XMLSchema-instance","Name": {"#text": "Name1"},"DeliveryAddress": {"Line1": {"@xmlns": "http://NamespaceTest.com/CommonTypes","#text": "Line11"},"Line2": {"@xmlns": "http://NamespaceTest.com/CommonTypes","#text": "Line21"}}}}';

var objectData = JSON.parse(data);

function CleanseData(_object) {
  var _currentObject = _object;
  for (var property in _currentObject) {
    if (property == "?xml" || property == "@xmlns") {
      delete _currentObject[property];
    }
    if (typeof(_currentObject[property]) == 'object') {
      CleanseData(_currentObject[property])
    }
  }
  return _currentObject;
}

var sanitizedData = JSON.stringify(CleanseData(objectData));

console.log(sanitizedData);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Creating JSON objects for kids in the R programming language

My dataset needs to be organized into JSON format. address city.x state.x latitude.x longitude.x 1 5601 W. Slauson Ave. #200 Culver City CA 33.99718 -118.40145 2 PO 163005 Austin ...

Stop ajax loading animation for a specific scenario

I usually have a global ajax load animation that runs during every ajax call. However, there are certain cases where I need to disable this effect. How can I achieve that? This is the code for the global animation : $(document).ajaxStart(function(){ $ ...

Unleashing the power of JSON decoding: Enforcing the transformation into

I have a Go struct where I need to unmarshal JSON data, everything works correctly except for the Values map which is of type map[string]string. type Data struct { Id int `json:"id"` Values map[string]string `json:"value ...

Where can I find the proper protocol to access API data in Swift?

I encountered an issue while trying to retrieve data from an API. The error message says: "The given data was not valid JSON", with a status code of 401. It seems like there might be an authentication problem. How can I properly set the auth credentials f ...

LazyBackground() - load background image lazily for a section identified by its ID

Iā€™m looking to implement lazy loading for a single image in a section identified by an ID, using the .lazy() method. The section has a background set through CSS. Here's the current code snippet: HTML <section id="showcase"> </section&g ...

When extracting information from JSON, storing unidentified data member names in a generic Dictionary<string, object> is a common practice

I am working with Swagger JSON data and using Newtonsoft.JSON to deserialize it. My object definition looks like this: public class WebService { public string swagger; public Dictionary<string, object> AllOthers; } The JSON data includes th ...

Explore various Lists with unique headings by applying filters or conducting searches

I am looking for a script that can filter and search various lists with the same class. The script should display the headings of the lists if there is at least one matching search name. If there are no matching search names, the heading of the list should ...

The function inputLocalFont.addEventListener does not exist and cannot be executed

Help needed! I created a code to add images using PHP and JS, but I'm encountering an error in my JS that says: inputLocalFont.addEventListener is not a function Here's the code snippet: <div> <img src="<?php echo $img_path.& ...

Creating an Express.js route that handles requests with various unique IDs

I am currently utilizing node.js with the express library. I have pages like localhost/page/1 and localhost/page/2 which are quite similar, but certain information needs to change based on the page ID. I am redirecting to these pages using a form submissio ...

Load the content of the dialog and transfer variables

After struggling for days, I am still unable to find a solution to my current dilemma. In my database, there are approximately 1300 items each with its own unique "id", a corresponding "name", and a property called "enabled". My goal is to display links t ...

What might be preventing me from accessing a json array of objects in this manner?

I recently created a test that needs to be modified because the original JSON file has changed. However, I am not very familiar with JSON and need to update the code. You can find the updated JSON file here. <!-- this is working fine --> ...

"Angular fails to retrieve any data from JSON API, returning a blank response

My ng-repeat function is not returning anything, and as a beginner in Angular, I am struggling to identify the error. Despite thorough error checking, I can't seem to figure out what's going wrong here. (function() { var app = angular.module( ...

Steps to successfully set up a React application without encountering any installation errors

Hey everyone, I've been trying to install React on my system for the past two days but keep encountering errors. Initially, I used the commands below to install the React app and it worked smoothly: 1. npm install -g create-react-app 2. create-react- ...

Change the controller's classes and update the view in Angular

In my angular application, I have a popup window containing several tabs. These tabs are styled like Bootstrap and need to be switched using Angular. The code for the tabs is as follows (simplified): <div class="settingsPopupWindow"> <div> ...

"Enhanced jQuery confirmation dialog plugin with full screen functionality and automatic

My current web-based production tracking system isn't getting the attention it needs from users, so I'm in the process of creating a full-screen alert and confirm function to ensure they pay closer attention. The idea is for alerts to remain on t ...

Converting Json data into an Excel spreadsheet format

There is a link to JSON-formatted data available here: Json Data I'm looking for the most efficient way to accomplish this task. I've heard it can be done with Python, but I'm not sure how to do it myself. ...

There is a delay in updating ng-if/ng-hide in real time on the HTML page

Assistance needed for implementing a slight adjustment in AngularJS with TypeScript. The requirement is to change the text of a button for 3 seconds upon clicking, then revert back to its original text. Two HTML elements are created for this purpose, each ...

Can a model be generated using Angular view values?

I am facing a challenge with a form that has complex functionality such as drag-and-drop, deleting groups of elements, and adding groups of elements. I want to leverage Angular for this task. The form is already rendered with original values set. <form ...

Using Express.js to Serve Static Content on a Dynamic Route

I am working with the app.js code below; app.use(express.static(__dirname + "/public")); app.use("/example", express.static(__dirname + "/public")); app.engine("html", require("ejs").renderFile); app.get("/", (req, res) => res.render("index.ejs")); a ...

Integrating Gesture Handling in Leaflet JS for two-finger scrolling enforcement

Have you ever noticed that when you're using a mobile device and scrolling down a webpage with a Google map, the map goes dark and prompts you to "Use two fingers to move the map"? https://i.stack.imgur.com/4HD1M.jpg I am interested in incorporating ...