2

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'
}
1

2 Answers 2

2

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));

Sign up to request clarification or add additional context in comments.

Comments

0

It's easy to write a function that does it for a single range. Write that function, then use reduce to do it repeatedly for each range. In this case, you want to make sure you do the end ranges first so it doesn't change the offset for prior ranges.

If you make sure you go through the ranges in reverse order (sort the array if necessary, or use reduceRight if they're already ordered), then it can be this simple:

// Wraps one range
function wrap(str, [i, j]) {
  const beg = str.substring(0, i),
        mid = str.substring(i, j),
        end = str.substring(j);
  return `${beg}<b>${mid}</b>${end}`;
}
[[2, 5], [11, 14]].reduceRight(wrap, 'brave new world')

So I'd write magic like this:

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.