Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

190
Views
Text replacements with splice do not work with smiles (or multibyte chars)

I have a problem with a complex replacement algorithm. In the end I was able to reduce the problem to this minimal code:

const input="test ๐Ÿ™„ hello test world"
let start = 0
let output = [...input]
const replacements = []
for (let end = 0; end <= input.length; end++) {
    const c = input[end]
    if (c == ' ') {
        if (start !== end) {
            const word = input.substring(start, end).toLowerCase()
            if (word == 'test') {
                replacements.push({start, length:(end - start), text:'REPLACEMENT'})
            }
        }
        start = end + 1
    }
}
for(let i=replacements.length-1;i>=0;i--) {
    output.splice(replacements[i].start, replacements[i].length, replacements[i].text)
}
console.log(output.join(''))

My input is "test ๐Ÿ™„ hello test world" and the expected output would be "REPLACEMENT ๐Ÿ™„ hello REPLACEMENT world", but it is actually "REPLACEMENT ๐Ÿ™„ hello tREPLACEMENTworld". I can remember from the Twitter API that JavaScript has a strange way to handle byte positions and char indices. So the issue is caused oblicious by the smiley.

How can I fix my code, so that the replacement works as expected? Bonus question why is that happening?

about 4 years ago ยท Juan Pablo Isaza
1 answers
Answer question

0

Well that was quick:

const input="test ๐Ÿ™„ hello test world"
let start = 0
let output = [...input]
const replacements = []
for (let end = 0; end <= output.length; end++) {
    const c = output[end]
    if (c == ' ') {
        if (start !== end) {
            const word = output.slice(start, end).join('').toLowerCase()
            if (word == 'test') {
                replacements.push({start, length:(end - start), text:'REPLACEMENT'})
            }
        }
        start = end + 1
    }
}
for(let i=replacements.length-1;i>=0;i--) {
    output.splice(replacements[i].start, replacements[i].length, replacements[i].text)
}
console.log(output.join(''))

When I use output array as input the indices work as expected and my replacement works again. However I will give anyone the accepted state who can explain why that change is required.

about 4 years ago ยท Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
ยฉ 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!