0

I'm working on a replacement process where I'm given a list of begin and end indicies saying I need to replace a word with tags. For instance, if I'm given the string below

"a lovely day at the office to meet such a lovely woman. I loved her so much"

I then see the list of indices below

[
   {
       beginOffset : 2,
       endOffset : 8
   },
   {
       beginOffset : 42,
       endOffset : 48
   },
   {
       beginOffset : 58,
       endOffset : 63
   }
]

Notice the word "lovely" isn't the only word I'm looking for. It's completely based on indexes. Below was my attempt but I'm running into so many problems trying to conceptualize what would make the most sense. I don't think regex would help me since its not a specific word. Anyone have experience doing something like this?

var indices = [{
    beginOffset: 2,
    endOffset: 8
  },
  {
    beginOffset: 42,
    endOffset: 48
  },
  {
    beginOffset: 58,
    endOffset: 63
  }
];

var teststring = "a lovely day at the office to meet such a lovely woman. I loved her so much";

let lastindex = 0;

indices.forEach(element => {
  var snippet = teststring.substr(lastindex, element["endOffset"])
  teststring = teststring.substr(lastindex, element["beginOffset"]) + '<b>' + teststring.substr(element["endOffset"], element["beginOffset"])

  // increment to account for the <b> brackets
  lastindex = element["endOffset"] + 7 + 1;
});

console.log(teststring);

The resulting string needs to look like this dynamically:

"a <b>lovely</b> day at the office to meet such a <b>lovely</b> woman. I <b>loved</b> her so much"
Barmar
  • 741,623
  • 53
  • 500
  • 612
booky99
  • 1,436
  • 4
  • 27
  • 45
  • 4
    Start from the end and work your way backwards so that you don't corrupt the indices. Build a function to replace a string at an index. https://stackoverflow.com/questions/1431094/how-do-i-replace-a-character-at-a-particular-index-in-javascript – Andy Ray May 12 '21 at 22:14
  • I'm not understanding how doing it backwards helps. If I'm still trying to evaluate indices based on modified and unmodified, there seems to be too many moving parts to do that, – booky99 May 12 '21 at 22:28
  • another idea: if you're allowed to store a separate string, you can loop through the input string and generate the resultString without ever modifying the input string. This may make it easier to conceptualize, but has tradeoffs in with runtime and memory – Toby Liu May 12 '21 at 22:32

3 Answers3

1

Just split the string and add map over the stringArray and add <b> just before the beginOffset and </b> after the endOffset.

var indices = [{
    beginOffset: 2,
    endOffset: 8,
  },
  {
    beginOffset: 42,
    endOffset: 48,
  },
  {
    beginOffset: 58,
    endOffset: 63,
  },
];

var teststring =
  "a lovely day at the office to meet such a lovely woman. I loved her so much";

let stringArray = teststring.split("");

indices.forEach(({
  beginOffset: begin,
  endOffset: end
}) => {
  stringArray = stringArray.map((l, index) => {
    if (index === begin - 1) {
      return [l, `<b>`];
    } else if (index === end - 1) {
      return [l, `</b>`];
    } else return l;
  });
});

console.log(stringArray.flat().join(""));
DecPK
  • 24,537
  • 6
  • 26
  • 42
0

Sort the indices from highest to lowest. Then when you insert <b> and </b> it won't affect the indexes in subsequent iterations.

var indices = [{
    beginOffset: 2,
    endOffset: 8
  },
  {
    beginOffset: 42,
    endOffset: 48
  },
  {
    beginOffset: 58,
    endOffset: 63
  }
];

var teststring = "a lovely day at the office to meet such a lovely woman. I loved her so much";

indices.sort((a, b) => b.beginOffset - a.beginOffset).forEach(({
    beginOffset,
    endOffset
  }) => teststring = teststring.substring(0, beginOffset) + '<b>' + teststring.substring(beginOffset, endOffset) + '</b>' + teststring.substr(endOffset));

console.log(teststring);
Barmar
  • 741,623
  • 53
  • 500
  • 612
0

I don't know if this is good solution or not but what I shortly resolved you can use

    let str = "a lovely day at the office to meet such a lovely woman. I loved her so much"

let o = [
   {
       beginOffset : 2,
       endOffset : 8
   },
   {
       beginOffset : 42,
       endOffset : 48
   },
   {
       beginOffset : 58,
       endOffset : 63
   }
]

const map = new Map()

o.forEach(function(v){
  map.set(v.beginOffset,'boff')
  map.set(v.endOffset,'eoff')
})

let b = ""
str.split("").forEach(function(s,k){
  let f = map.get(k)
  if(f){
     if(f === "boff"){
        b += "<b>"
     }else{
       b += "</b>"
     }
  }
   b +=s
})

console.log(b)