How can I substitute specific words in a string with multiple words from an array?

I'm faced with a challenge where I need to replace asterisks (*) in a sentence with words from an array. Let's take an example:

let sentence = 'My * is * years old.';
let words = ['dog', 3];

//expected result => My dog is 9 years old.

What's the best way to achieve this without resorting to regex? Also, how should I handle cases where there are more asterisks than elements in the array like so:

let sentence = 'The soldiers marched *, *, *, *.';
let words = ['left', 'right'];

//expected result => The soldiers marched left, right, left, right.

Are there any vanilla JS solutions for this problem?

Answer №1

To ensure the index stays within bounds, consider using a replacement function that includes an initial index value. The default starting index is set to zero.

One way to manage the index is by utilizing the remainder operator % in conjunction with the array's length.

const
    replace = (string, array, i = 0) =>
        string.replace(/\*/g, _=> array[i++ % array.length]);

console.log(replace('My * is * years old.', ['dog', 3]));
console.log(replace('The soldiers marched *, *, *, *.', ['left', 'right']));

Answer №2

let statement = 'Her * is * years old.';
let values = ['cat', 7];
let counter = 0;
while (statement.indexOf('*') > -1) {
    statement = statement.replace('*', values[counter++]);
    if (counter >= values.length) counter = 0;
}
console.log(statement);

displays: "Her cat is 7 years old."

Answer №3

If you're not a fan of regular expressions, here's an alternative approach:

words = ["start", "end"];
"The students ran *, *, *, *.".split("*").map(function (x, i) {
  return i === 0 ? x : words[(i + 1) % words.length] + x;
}).join("");

Step-by-step breakdown:

init  | "The students ran *, *, *, *."
split | ["The students ran ", ", ", ", ", ", ", "."]
i = 0 | ["The students ran ", ", ", ", ", ", ", "."]
i = 1 | ["The students ran ", "start, ", ", ", ", ", "."]
i = 2 | ["The students ran ", "start, ", "end, ", ", ", "."]
i = 3 | ["The students ran ", "start, ", "end, ", "start, ", "."]
i = 4 | ["The students ran ", "start, ", "end, ", "start, ", "end."]
join  | "The students ran start, end, start, end."

Answer №4

Here's an alternative way to achieve the same result without using regular expressions:

s = "The soldiers marched *, *, *, *.";
f = Function("words", "var i = 0; return \"" + s.split("*").join(
  "\" + words[(i++) % words.length] + \""
) + "\";");
> | f(["L", "R"])
< | "The soldiers marched L, R, L, R."
> | f(["L", "R"].reverse())
< | "The soldiers marched R, L, R, L."
> | f(["L", "R", "R"])
< | "The soldiers marched L, R, R, L."

However, be cautious of potential malicious code:

s = "The soldiers marched *, *, *, *.";
s = "\", console.log(\"VIRUS ATTACK!!! CALL +XX-XXXXX-XXXXX NOW!!!\"), \"" + s;
f = Function("words", "var i = 0; return \"" + s.split("*").join(
  "\" + words[(i++) % words.length] + \""
) + "\";");
> | f(["L", "R"])
  | VIRUS ATTACK!!! CALL +XX-XXXXX-XXXXX NOW!!!
< | "The soldiers marched L, R, L, R."

Always make sure to sanitize user input:

s = "The soldiers marched *, *, *, *.";
s = "\", alert(\"VIRUS ATTACK!!! CALL +XX-XXXXX-XXXXX NOW!!!\"), \"" + s;
s = s.split("\"").join("\\\""); // may not be completely secure!
f = Function("words", "var i = 0; return \"" + s.split("*").join(
  "\" + words[(i++) % words.length] + \""
) + "\";");
> | f(["L", "R"])
< | "", alert("VIRUS ATTACK!!! CALL +XX-XXXXX-XXXXX NOW!!!"), "The soldiers marched L, R, L, R."

Remember, it's always best to err on the side of caution when handling user input :-|

Answer №5

Exploring characters sequentially:

input = "The soldiers marched *, *, *, *. ";
words = ["up", "down"];
output= ""
for (i = 0, j = 0; i < input.length; i++) {
  output += input[i] !== "*" ? input[i] : (
    words[(j++) % words.length]
  );
}
console.log(output)

As evident from the code above, there exist different approaches to handling string manipulations besides using regular expressions. However, it is crucial to grasp the concept of the modulo operator (%):

0 % 2 = 0 | 0 -> 0
1 % 2 = 1 | 1 -> 1
2 % 2 = 0 | 2 -> 0
3 % 2 = 1 | 3 -> 1
4 % 2 = 0 | 4 -> 0

The cyclic pattern of 0s and 1s depicted by the modulo operation ensures that the result never exceeds the right operand. This principle proves especially handy when needing to cycle through an array multiple times:

abc = ["X", "Y", "Z"]
for (i = 0; i < 2 * abc.length; i++) {
  // j will always stay within the bounds of abc
  j = i % abc.length; // 0, 1, 2, 0, ...
  console.log(i, j, abc[j]);
}

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

Adjust the formatDate function in the Material UI datepicker

I recently implemented the material-ui datepicker component with redux form and it's been working great. However, I have encountered a minor issue. Whenever I change the date, it displays in the input field as yyyy-mm-dd format. I would like it to app ...

What is the best way to mix up the images in my memory game?

My JavaScript memory game is functioning properly, but I would like the images to load in a random order. Unfortunately, I'm not sure how to accomplish this. Here is the current setup: var easyImages = ["img/bat.jpg", "img/bug.jpg", "img/cat.jpg", " ...

What is the most effective way to compare two arrays of objects in JavaScript?

I'm working on a function that needs to return an array of elements based on certain filters. Here is the code for the function: filter_getCustomFilterItems(filterNameToSearch: string, appliedFilters: Array<any>) { let tempFilterArray = []; ...

Learn how to implement a call to 'next()' in Express and Node.js only after successfully creating schemas

I am currently developing an event app, and within my 'Event' schema, I have an array of 'Tag' schemas, allowing each event to be associated with one or more tags. Event: var EventSchema = new Schema({ ... tags: [{ type: Schema.Type ...

A jquery class for styling with CSS

I am looking to add a CSS class to a gridview. I attempted to use this style from a reference link, so I implemented the following code snippet: $(function () { $('[ID*=search_data]').on('click', function () { var fromda ...

a new approach for creating a conditional function in pointfree fashion

Can someone help me convert this code into a pointfree style? To provide context: The function receives an Array of Either types and returns a Task type. If any of the Either types have the left set, the Task type is rejected with that value. If none of t ...

in node.js, virtual machine scripts can import modules using the require function

I am currently developing a command-line interface using node.js that runs an external script > myapp build "path/to/script.js" myapp is a node.js application that executes the script provided as a command-line argument. In simple terms, it performs ...

Utilizing Json data with Jquery for dynamically placing markers on Google Maps

Seeking assistance as I am currently facing a problem where I need to loop through JSON data and add it as markers on Google Maps, but unfortunately, it only returns null value. Is there a way to automatically connect this to JSON? My plan is to have a Gr ...

ASP.NET CodeBehind Fails to Recognize Changes in TinyMCE Textarea

I have multiple <asp:TextBox TextMode="MultiLine"> elements on a webpage. Initially, I populate them using VB code behind and then convert them into TinyMCE editors with the help of the jQuery TinyMCE plugin. Each text box has an associated button fo ...

Remove the class upon clicking

I recently created a toggle-menu for my website that includes some cool effects on the hamburger menu icon. The issue I am facing is that I added a JavaScript function to add a "close" class when clicking on the menu icon, transforming it into an "X". Whil ...

What is causing the return statement to not function properly in the Mongoose findOne method?

I am attempting to locate an item by its name, then update the table and return the updated result. However, the return statement is not working as expected in my code: class addSongsToArtist { constructor(artistName) { Artist.findOne({ ...

Choose three different images and one corresponding word from a JavaScript array to be displayed individually on the screen in separate div containers

I am in the process of developing a web game that will showcase 3 images on the screen, and the player must select the image that corresponds to the displayed word. I have successfully created a JavaScript array containing the images and words retrieved fr ...

Handling a change event for a mat-datepicker in Angular 7 can be tricky, especially when its value is tied to an optional input parameter. Let's dive into how to

I've recently started working with angular development and encountered a challenge with a mat-datepicker. The value of the datepicker is connected to filterDate using [(ngModel)] as an @Input() parameter. I have implemented a handleChange event that e ...

Wait to display the page until all AngularJS directives have finished loading their HTML content

I've encountered an issue in my AngularJS application where I created directives that load external HTML templates from another URL. The problem is that when I navigate to the page, the binding works fine but the directive's HTML doesn't loa ...

Generate a selection of complementary, triadic, and monochromatic color palettes using just one hex color code

My goal is to generate three unique color palettes based on a single hex/rgb value given by the user. The first palette will feature the complementary color of the initial input, followed by a full range of colors in subsequent palettes. I aim to expand be ...

Problem encountered with PDFKit plugin regarding Arabic text rendering

When it comes to generating dynamic PDF files, I rely on the PDFKit library. The generation process is smooth, but I'm encountering difficulties with displaying Arabic characters even after installing an Arabic font. Additionally, although the Arabic ...

Error: Express is undefined and does not have a property called 'use'

I'm encountering a problem with my express server specifically when I utilize the 'app.use' command. Within my task-routes.js file, the following code is present: import express from 'express'; const router = express.Router(); ...

Are $(function() { }) and $(document).ready(function() { }) the same function under the hood?

Similar Question: What sets apart these jQuery ready functions? Do $(function(){}); and $(“document”).ready(function(){}); have the same meaning? Beginning javascript code with $(function, etc. This day, as I was examining some jav ...

Adjust the scrollbar color when hovering over a particular div

Is there a way to change the color of a div's scrollbar when hovering over the div without assigning an id to it? I've attempted the following methods so far: div:hover { ::-webkit-scrollbar {color: black} } and div:hover + ::-webkit-scroll ...

Seeking a proficient Cloud Code specialist skilled in JavaScript, focused on managing installations and channels

My experience with Javascript is limited, but as I work on my application, I realize the necessity of incorporating it into Cloud Code. I have a Parse class called Groups where I store group data including Name, Description, Users, and Requests. Name, Des ...