Updating multiple values within a JSON object, jsObject, or string

After receiving a response from a web service, I need to replace certain values in the response with custom values that I have defined.

One possible approach is to create a tree traverser to identify the specific values and replace them with the custom values.

The original response looks like this:

[
  {
    "name": "n1",
    "value": "v1",
    "children": [
      {
        "name": "n2",
        "value": "v2"
      }
    ]
  },
  {
    "name": "n3",
    "value": "v3"
  }
]

Here is my custom mapping:

const map = {
  "v1": "v11",
  "v2": "v22",
  "v3": "v33"
};

What I wish to achieve is:

[
  {
    "name": "n1",
    "value": "v11",
    "children": [
      {
        "name": "n2",
        "value": "v22"
      }
    ]
  },
  {
    "name": "n3",
    "value": "v33"
  }
]

I am considering the idea of converting the response to a string and then using a custom regular expression to replace the values based on my map.

  1. Would this method be more efficient than using a tree traverser?
  2. If so, what would be the best way to implement it?

It would look something like this:

originalString.replace(regexp, function (replacement))

Answer №1

The efficiency of tree traversal over regex

It's worth noting that while some aspects could be optimized in the regex implementation, there are clear bottlenecks that need to be addressed.

Reasons behind the slowness of regex:

There might be multiple factors contributing to the slow performance of regex, but one major issue stands out:

When you utilize regex for finding and replacing, it involves generating new strings each time and executing matches repeatedly. This can make regex expressions quite costly, and despite my implementation not being overly expensive, performance is still impacted.

Advantages of tree traversal in terms of speed:

With tree traversal, direct object modification takes place without the need for creating new string objects or any additional objects. Additionally, there is no need for a full string search every time, leading to improved efficiency.

RESULTS

Run the performance test provided below. The test employs console.time to measure the duration. It becomes evident that tree traversal significantly outperforms regex.

function usingRegex(obj, map) {
  return JSON.parse(Object.keys(map).map(oldValue => ({
    oldValue,
    newValue: map[oldValue]
  })).reduce((json, {
    oldValue,
    newValue
  }) => {
    return json.replace(
      new RegExp(\`"value":"(${oldValue})"\`),
      () => \`"value":"\${newValue}"\`
    );
  }, JSON.stringify(obj)));
}

function usingTree(obj, map) {
  function traverse(children) {
    for (let item of children) {
      if (item && item.value) {
        item.value = map[item.value];
      }
      if (item && item.children) {
        traverse(item.children)
      }
    }
  }
  
  traverse(obj);
  return obj; // mutates
}

const obj = JSON.parse(\`[
  {
    "name": "n1",
    "value": "v1",
    "children": [
      {
        "name": "n2",
        "value": "v2"
      }
    ]
  },
  {
    "name": "n3",
    "value": "v3"
  }
]\`);

const map = {
  "v1": "v11",
  "v2": "v22",
  "v3": "v33"
};

// Verify the functionality of each function
console.log('== TEST THE FUNCTIONS ==');
console.log('usingRegex', usingRegex(obj, map));
console.log('usingTree', usingTree(obj, map));

const iterations = 10000; // ten thousand
console.log('== DO 10000 ITERATIONS ==');
console.time('regex implementation');
for (let i = 0; i < iterations; i += 1) {
  usingRegex(obj, map);
}
console.timeEnd('regex implementation');

console.time('tree implementation');
for (let i = 0; i < iterations; i += 1) {
  usingTree(obj, map);
}
console.timeEnd('tree implementation');

Answer №2

Is there a faster solution than tree traversal?

It's hard to say for sure. The speed of the solution may vary depending on factors such as input size and the complexity of the replacement map. One way to find out is to conduct performance tests on platforms like JSPerf.com.

If so, what is the best approach?

For a quick and efficient string replacement process without the need for special escaping, a regex-based solution can be used. Here is an example code snippet:

const input = [
  {
    "name": "n1",
    "value": "v1",
    "children": [
      {
        "name": "n2",
        "value": "v2"
      }
    ]
  },
  {
    "name": "n3",
    "value": "v3"
  }
];

const map = {
  "v1": "v11",
  "v2": "v22",
  "v3": "v33"
};

const regex = new RegExp(':\\s*"(' + Object.keys(map).join('|') + ')"', 'g');

const json = JSON.stringify(input);
const result = JSON.parse(
  json.replace(regex, function(m, key) { return ': "' + map[key] + '"'; })
);

console.log(result);

Answer №3

The speed of a traverser can greatly surpass that of an iterator when performing string replacements, as the traverser interacts with each individual character in the final string, whereas the iterator may skip over certain items in the process.

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

Formatting Strings in JavaScript when saving as a .txt file with proper indentation

Utilizing Angular and TypeScript/JavaScript for testing purposes. Each row has been formatted with a newline at the end of the code. formattedStr += car.Name + ' | ' + car.Color + ' | ' + car.Brand + '\r\n' The da ...

In JavaScript, alert a message once all images have been clicked

I'm encountering a small issue with my javascript code. I am developing a game for a school project where the objective is to click (remove) fish using a fishing rod. However, the game does not have an end condition set up, so players cannot win. Belo ...

Can we use an open-ended peer version dependency in package.json?

Question Summary Is it necessary for me to specify the peer dependency of @angular/core in my package.json file for a package containing easing functions that work with any version of Angular? "peerDependencies": { "@angular/core": "x.x" } Context I ...

What do you prefer: defining properties with the JSON object or with objectName.property in JavaScript

Can you tell me which approach is considered the best practice? Is it better to use the "this" statement in the following way: var obj = { x: 20, y: 10, width: this.x, height: this.y, render: function () { // renders object on canvas ctx.fi ...

Experiencing a blank array when using filtering/search text in a Nodejs application with MongoDB

I am experimenting with search functionality in a MongoDB database using Node.js. However, my result array is always empty. I have shared my code here and would appreciate some assistance in identifying the issue. Whenever I perform a search, I end up with ...

Jquery countdown that persists even after refreshing the page with F5

Currently, I am in search of a jquery plugin for a countdown feature that will retain the timer even if the page is refreshed. I am developing an application for a questionnaire and I would like to display a countdown timer set to 60 minutes. In my applica ...

Messages traced by log4javascript are not being displayed

I am currently utilizing log4javascript version 1.4.3. Everything in my application seems to be functioning correctly with all log levels except for trace. To simplify the troubleshooting process and ensure that the issue does not lie within my applicati ...

Is it necessary to have NodeJs in order to host a React app on a server?

I've been working on a .NET Core 2.2 project with React integration, As I'm nearing completion of the project, I have a query that has been on my mind. Do I need Node.js installed on the server for React to function properly? Thank you. ...

Getting map data from Mapbox and displaying it on an HTML page

I have been working with Mapbox GL JS and successfully retrieved data in the console. However, I am facing issues when trying to display this data on an HTML page. Can anyone assist me with this problem? I specifically need the data inside mapdata to be sh ...

Contrasting onevent with addEventListener

After studying various DOM events, I attempted to implement the 'blur' event on the HTML body. My first attempt was with onblur document.body.onblur = () => { dosomething(); } and I also tried using AddEventListener document.body.addEven ...

What is the best method for transferring images to a node.js server using Axios?

Is there a method to utilize axios for sending an array of images or a single image to node? My current axios code (implemented in react js on the frontend): onFormSubmit(event){ event.preventDefault(); let payload = this.state; console.log(" ...

I am looking to host several iterations of jQuery on a content delivery network within my Nuxt application

Currently, we are loading jQuery 3.1.4 externally from a CDN on the top page. index.vue head: { bodyAttrs: { id: 'overview' }, script: [ { src: 'https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min ...

Finding your way to a particular section within a webpage through an external source

Hey there! I'm currently working on creating a link that will direct users to a specific section within my webpage. For example, redirecting them to https://blabla.github.io/my-website. My code is quite straightforward and it functions properly when ...

Failure of regex expression when applied to a string

I am currently working with DataDog and facing a challenge in extracting the value of a variable from the JSON output to use it in subsequent requests. The issue lies in the fact that the JSON output contains escaped characters (), making it difficult for ...

How can I implement a redirect back to the previous query page post-authentication in Next.js 13?

To enhance security, whenever a user tries to access a protected route, I plan to automatically redirect them to the login page. Once they successfully log in, they will be redirected back to the original protected route they were trying to access. When w ...

Is there a way to incorporate HTML code into a fullCalendar 4 event title?

Is it possible to add HTML content to an event title using eventRender in FullCalendar version 4? document.addEventListener('DOMContentLoaded', function() { var calendarEl = document.getElementById('calendar'); var calendar = new ...

Unlocking the potential: Clicking on all ng-if elements with matching text using Chrome console

I am currently trying to determine how to automatically click on all elements that have a specific state. The page appears to be built using Angular, although I am unsure of the exact version being used. My approach involves using the console in Chrome t ...

Scrapy generates faulty JSON output

I have implemented the following parsing method: def parse(self, response): hxs = HtmlXPathSelector(response) titles = hxs.select("//tr/td") items = [] for titles in titles: item = MyItem() item['title'] = titles. ...

Consistently Incorrect Date Formatting in Bootstrap Display

I have a potential issue with my date display. It should show a default "Start Date" in a short date format, but when the "Sale Date" DropDownBoxFor is toggled, it should display an AJAX result date. However, the display always appears in a date and time f ...

Using Node.js to download and install npm packages from the local hard drive

Is there a way to add an npm package to my Node.js project from my hard drive? It seems like the admin at work has restricted access to npm. I managed to install npm, but whenever I attempt to run "npm install express" in the command line, I keep getting ...