Home > Back-end >  interpolate string from index ranges
interpolate string from index ranges

Time:12-03

I have an array of index ranges and a string:

const ranges = [[2,5], [11, 14]]
const str = 'brave new world'

I'm trying to write a function to interpolate and wrap the characters at those ranges.

const magic = (str, ranges, before='<bold>', after='</bold>') => {
  // magic here
  return 'br<bold>ave</bold> new w<bold>orl</bold>d'
}

Any magician out there ? Thank you.

CodePudding user response:

Assuming your ranges are in the order they need to be applied, then:

  1. Iterate over the ranges.
  2. Add the part of the string previous the start of the range to the result.
  3. Wrap the middle part in the before and after.
  4. Remember which is the last index you processed then repeat 2.-4. for as many ranges there are.
  5. Add the rest of the string after the last range to the result.

const magic = (str, ranges, before='<bold>', after='</bold>') => {
  let result = "";
  let lastIndex = 0;
  
  for(const [start, end] of ranges) {
    result  = str.slice(lastIndex, start);
    const wrap = str.slice(start, end);
    result  = before   wrap   after;
    lastIndex = end;
  }
  
  result  = str.slice(lastIndex);
  
  return result;
}

const ranges = [[2,5], [11, 14]]
const str = 'brave new world'
console.log(magic(str, ranges));

CodePudding user response:

Sure, here's one way you can solve this problem:

const magic = (str, ranges, before='<bold>', after='</bold>') => {
  // Create an array of characters from the input string
  const chars = str.split('');

  // Iterate over the ranges
  for (const [start, end] of ranges) {
    // Insert the before and after strings at the start and end indices
    chars.splice(end, 0, after);
    chars.splice(start, 0, before);
  }

  // Join the characters and return the resulting string
  return chars.join('');
}

const ranges = [[2, 5], [11, 14]];
const str = 'brave new world';
const wrappedString = magic(str, ranges);

console.log(wrappedString); // "br<bold>ave</bold> new w<bold>orl</bold>d"

I hope this helps! Let me know if you have any questions.

CodePudding user response:

If you make sure you go through the ranges in reverse order (call .reverse() on the array if it helps, or sort the array if necessary), then it can be this simple:

// Wraps one range
function wrap(str, [i, j]) {
  return str.substring(0, i)   '<b>'   str.substring(i, j)   '</b>'   str.substring(j);
}
[[2, 5], [11, 14]].sort(([i], [j]) => j - i).reduce(wrap, 'brave new world')

So I'd write magic like this:

function magic(str, ranges, b='<bold>', a='</bold>') {
  ranges = ranges.sort(([i], [j]) => j - i);
  const wrap = (str, [i, j]) => str.substring(0, i)   b   
                                str.substring(i, j)   a   str.substring(j);
  return ranges.reduce(wrap, str);
}
  • Related