简体   繁体   中英

Replace multiple strings between two indexes with in strings

I have a string. I want to replace substrings with in string. For each substring I have the starting and ending index. Using regex is out of scope.

So from let str = "I want chicken pizza and cheese pizza from point restaurant";

The expected result would be like this.

I want TYPE1 TYPE4 and TYPE1 pizza from point restaurant

 let str = "I want chicken pizza and cheese pizza from point restaurant"; let roles = [{ "start": 7, "end": 14, "typeId": "TYPE1", "type": "toppings", "text": "chicken" }, { "start": 25, "end": 31, "typeId": "TYPE1", "type": "toppings", "text": "cheese" }, { "start": 15, "end": 20, "typeId": "TYPE4", "type": "main ingredient", "text": "pizza" } ]; let styledStr = str; roles.map(r => { const { start, end, typeId, text } = r; let strArr = str.split(''); let removeStr = strArr.splice(start, end, typeId); styledStr = strArr.join(''); console.log(styledStr); });

  1. Do not use a map if you do not need a
  2. No need to split unless you MUST use splice

Method using start and end - note I sort the roles so we start at the highest position

 let str = "I want chicken pizza and cheese pizza from point restaurant"; let roles = [{ "start": 7, "end": 14, "typeId": "TYPE1", "type": "toppings", "text": "chicken" }, { "start": 25, "end": 31, "typeId": "TYPE1", "type": "toppings", "text": "cheese" }, { "start": 15, "end": 20, "typeId": "TYPE4", "type": "main ingredient", "text": "pizza" } ]; let styledStr = str; roles.sort((a,b)=>b.start-a.start) roles.forEach(r => { const { start, end, typeId, text } = r; // Using substring because it is more readable and saves a split styledStr = styledStr.substring(0,start) + typeId + styledStr.substring(end) styledStr.slice(start,end,typeId) }); console.log(styledStr)

Method using text replace

 let str = "I want chicken pizza and cheese pizza from point restaurant"; let roles = [{ "start": 7, "end": 14, "typeId": "TYPE1", "type": "toppings", "text": "chicken" }, { "start": 25, "end": 31, "typeId": "TYPE1", "type": "toppings", "text": "cheese" }, { "start": 15, "end": 20, "typeId": "TYPE4", "type": "main ingredient", "text": "pizza" } ]; let styledStr = str; roles.forEach(r => { const { start, end, typeId, text } = r; console.log(start,end,text) styledStr = styledStr.replace(text,typeId) }); console.log(styledStr)

By replacing certain words, you are changing the length of the String, and thus your indices start and end won't hold the correct values anymore.

Also, you always start with str.split() , meaning you override a previous replacement saved in styledStr . This is the reason why only one replacement is visible at the end.

You should use Array.forEach() when performing actions based on the array's items, and use Array.map() to get a new array mapped from the old one.
Array.forEach() is what should be used here.

You can fix your code by starting the replacement from the back.

  1. Sort roles in regards to either start or end in descending order
  2. Replace in styledStr
  3. Log to console

 let str = 'I want chicken pizza and cheese pizza from point restaurant'; let roles = [ { start: 7, end: 14, typeId: 'TYPE1', type: 'toppings', text: 'chicken' }, { start: 25, end: 31, typeId: 'TYPE1', type: 'toppings', text: 'cheese' }, { start: 15, end: 20, typeId: 'TYPE4', type: 'main ingredient', text: 'pizza' } ]; let styledStr = str; // Start with raw string // 1. Sort `roles` (will be in ascending order; reverse to get descending order) roles.sort((o1, o2) => { if (o1.start < o2.start) return -1; if (o1.start == o2.start) return 0; return 1; }).reverse(); // 2. Replace roles.forEach(i => { let arr = styledStr.split(''); // Transform `styledStr` instead of `str` arr.splice(i.start, (i.end - i.start), i.typeId); styledStr = arr.join(''); // Save transformation in `styledStr` }); // 3. Log to Console console.log(styledStr);

enter code here

 let roles = [{ "start": 7, "end": 14, "typeId": "TYPE1", "type": "toppings", "text": "chicken" }, { "start": 25, "end": 31, "typeId": "TYPE1", "type": "toppings", "text": "cheese" }, { "start": 15, "end": 20, "typeId": "TYPE4", "type": "main ingredient", "text": "pizza" } ]; let str= `I want ${roles[0].typeId} ${roles[2].typeId} and ${roles[0].typeId} pizza from point restaurant` console.log(str)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM