Wildcard for keys in JavaScript objects and JSON

I have a JSON object that contains specific key-value pairs, and I am attempting to manipulate strings based on this object. Here is an example of the JSON structure:

{
    "foo %s": "bar %s",
    "Hello %s world %s.": "We have multiple %s %s."
}

My goal is to use this object to transform input strings using placeholders indicated by "%s". For instance:

  • foo bar -> matches foo %s -> should result in bar bar
  • Hello foo world bar. -> matches Hello %s world %s. -> should result in We have multiple foo bar

Currently, I have implemented some code that partially achieves this functionality but has limitations. It only works for one "%s" at a time and requires spaces around it. Here is the code snippet:

let str = "input here";
let obj = {
        "foo %s": "bar %s",
        "Hello %s world %s.": "We have multiple %s %s."
    },
    pieces = str.split(" "),
    output;
for (let j in pieces) { // loop through indices
    let tempPieces = pieces.map(u => u); // create local array copy
    tempPieces[j] = "%s"; // replace the index with %s
    if (obj[tempPieces.join(" ")]) { // check if this pattern exists in the object
        output = obj[tempPieces.join(" ")].replace("%s", pieces[j]); // combine the array and subtitute %s from the value
        break;
    }
}

Do you have any suggestions or improvements for this approach?

Answer №1

To change your object into regular expressions, you can then apply them by calling String.prototype.replace.

For instance, here is an example with a single defined replacement operation:

console.log('Hello foo world bar.'.replace(/^Hello (.*?) world (.*?) bar\.$/, 'We have multiple $1 $2.'))
// Output: We have multiple foo bar.

In this case, we match the entire string - if it matches the pattern, the complete content will be replaced.

The transformation of "Hello %s world %s." to /^Hello (.*?) world (.*?)\.$/ (with (.*?) representing a non-greedy capture group containing any characters) and

"We have multiple %s %s."
becoming
"We have multiple $1 $2."
(with $x referring to the contents of the x-th capture group) is necessary for achieving this result.

A function could be implemented as follows:

function replaceTemplates (str, templates) {
  const escapeRegExp = s => s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
  
  for (const [template, replacement] of Object.entries(templates)) {
    const re = new RegExp('^' + escapeRegExp(template).replace(/%s/g, '(.*?)') + '$')
    
    if (re.test(str)) {
      let i = 1 
      const reReplacement = replacement
        .replace(/\$/g, '$$$$')
        .replace(/%s/g, () => '$' + i++)
      
      return str.replace(re, reReplacement)
    }
  }
  
  return str
}

const templates = {
  'foo %s': 'bar %s',
  'Hello %s world %s.': 'We have multiple %s %s.'
}

console.log(replaceTemplates('foo bar', templates)) // Output: bar bar
console.log(replaceTemplates('Hello foo world bar.', templates)) // Output: We have multiple foo bar.

Just a side note: If pp = p.map(u => u) is meant to create a copy, consider using pp = p.slice() or pp = [...p] instead.

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

Tips to prevent redirection in a JavaScript function

When a user clicks on a specific link, the HideN function is triggered. Here's an example: <a href="<?php echo $dn5['link']; ?>" onclick="HideN('<?php echo $dn5['id'];?>','<?php echo $dn5['fro ...

What is the best way to decode a complex JSON in a Flutter application?

I need assistance with parsing a complex JSON in Flutter. Despite trying various methods, I am still unsure about the process. Can someone provide guidance on how to approach this situation? { "message": { "header": { " ...

Updating Array Values in AngularJS based on Input Text Box Modifications

In my application, there is a text box that looks like this - <input type="text" class="form-control" id="inputID" name="ItemId" ng-model="inputItemId" ng-required="true" ng-blur="addValueToArray(inputItemId)"/> The user has the ability to add or r ...

Freemarker substitute & and &ampersand;

I am facing an issue with Freemarker. I need to eliminate all the special characters from this sentence as well as from similar sentences in the future: BLA BLA RANDOM &, RANDOM BLA In particular, I want to remove the & character. The platform ...

The preventDefault method is failing to prevent the default action when placed within a

I am having trouble using preventdefault to stop an action. I'm sorry if the solution is obvious, but I can't seem to locate the mistake. Why isn't it preventing the link from being followed? Here is a link to my jsfiddle: http://jsfiddle.ne ...

Is there a way to streamline this query code that seems overly complex?

Could someone please assist me in simplifying this code? I am trying to shorten or simplify the query code by using a stored procedure, but I still need to include the details inside the "()" parentheses. I am new to Node.js and would appreciate any help. ...

Comparing .innerHTML with createElement() | Exploring setAttribute() versus the Direct method*

Someone mentioned that this approach was not considered "proper", but I didn't pay much attention to it until I encountered a run-time error in IE9. Now, I need help converting the code to utilize object properties instead. What is the reason behind i ...

Having difficulty locating the index of the column labeled `Clients` within a table; the result being -1

Having some trouble locating the index of the column name Customers within a table using jQuery/javascript. No matter what I try, it always returns -1 let tableDatacy = "Results_Table"; let columnName = "Customer"; let tableHeaders = [] ...

Style the code presented within a div tag

I am in the process of creating a JavaScript-powered user interface that can generate code based on user interactions. While I have successfully implemented the code generation functionality and saved the generated code as a string, I am facing difficultie ...

Run an npm script located in a different package

Imagine I have two node packages, one named parent and the other named child. The child package contains a package.json file with some scripts. Is it viable to merge the scripts from child into the context of parent? For instance: child/package.json: "s ...

Error: Trying to access 'product-1' property on an undefined object

Having trouble displaying JSON data in my React.js project, I've been stuck on an error for the past couple of days with no luck in solving it. The JSON data is stored in a file named products.json: { "product-1": [ { ...

Repeatedly Triggered JQuery AJAX Calls

On my web page, I have implemented a feature that allows users to search for an address using a GIS server's web-service. This functionality is triggered by a button click event which calls a JQuery AJAX method. Upon successful retrieval of address da ...

Interested in creating a weather application that changes color based on the time of day

My attempt to create a weather app with a glowing effect has hit a roadblock. I want the app to glow "yellow" between 6 and 16 hours, and "purple" outside of those hours. I have assigned classes for AM and PM elements in HTML, and styled them accordingly i ...

Is it possible to swap a <div> element with the content of another HTML page using the .innerHTML method?

I am currently working on a project that involves loading different webpages into a <div> on my page once specific links are clicked. I came across a thread about using jQuery for this purpose, but I'm not familiar with it. Is there a way to ach ...

The Yeoman Angular Coffee router is not routing properly and displays an error message "cannot GET"

Struggling with getting the router to load a basic template after setting up a Yeoman angular scaffolder installation. Here's my configuration: // index.html <body ng-app="mvmdApp"> <div class="container" ng-view=""></div>// not ...

Can you add a variable to a string once the string has already been formed?

Is there a way to change the quotes of a string from double or single quotes to backticks in JavaScript after it has already been defined? I need to be able to add variables into the string. I attempted using replace(), but it seems like the variable is n ...

Vue.js Interval Functionality Malfunctioning

I'm brand new to Vuejs and I'm attempting to set an interval for a function, but unfortunately it's not working as expected. Instead, I am encountering the following error: Uncaught TypeError: Cannot read property 'unshift' of u ...

Tips for transmitting a batch of resources with Restangular?

Suppose I need to make a DELETE request to delete multiple products from the resource /products. The complete request should be sent to this URI: /products/ids=1&ids=2&ids=3 What is the method to send a request like this using Restangular? The c ...

Receiving communication without the need for port forwarding

My goal is to establish a system where a server can send messages to clients at any given time, ensuring that when a message is sent, it is received almost immediately (ideally within 1 second or less). I am looking for a way to achieve this without having ...

Click on the button to retrieve the data from the table cell

I have a table created using JavaScript <table class="table"> <thead> <tr> <th scope="col">#</th> <th scope="col">City</th> <th scope="col">Region</th> </tr> < ...