1

I have two large corresponding find/replace vectors eg

find = [find1,find2,find3...]
replace  = [replace1,replace2,replace3...]

The find and replace vectors contain string vars.

The question is about is the most efficient way to run a complex find/replace all on a large body of text.

I'm currently using a split/join, eg:

 var.split(foo).join(bar1)) 

This works, but (unsurprisingly) as var gets larger and the find replace vectors get more complicated, the operation slows substantially as var is repeatedly expanded and contracted with each replacement.

I'm considering:

  • Switch to a find/replace using regex
  • Trying to introduce a bit of async

But I'm interested in what this community knows, or if anyone has tried anything similar and has observations?

Rookie
  • 25
  • 5
  • 2
    Could you clarify a bit? *What* is the data you want to find/replace? *What* are the actual find/replace vectors that you're using? *What* is your current implementation (in code)? https://stackoverflow.com/help/mcve – Sven Oct 12 '17 at 11:15
  • @Svenskunganka thanks for the reply. I didn't paste the vectors because they each contain thousands of elements. The elements are text strings though, if that is helpful. There is no reliable relationship between find1 and replace1. – Rookie Oct 12 '17 at 11:21
  • What you're asking is too broad. There is no definite answer to this question, as the efficiency varies greatly depending on the actual data you want to perform a find/replace operation on. – Sven Oct 12 '17 at 11:25
  • related :https://stackoverflow.com/questions/15604140/replace-multiple-strings-with-multiple-other-strings – Drag and Drop Oct 12 '17 at 11:27

1 Answers1

2

String are immutable in JavaScript, so you can't change it in-place. Here is my implementation. I turn it into an array of words and search an object of find-replace key-value pairs. O(1) lookup, O(n) for splitting, replacing, and joining.

const findReplace = {
  find1: 'replace1',
  find2: 'replace2',
  find3: 'replace3'
}
const textBody ='find1 find2 word word2'
const textArray = textBody.split(" ")
const replacedArray = textArray.map(word => {
  return findReplace[word] ? findReplace[word] : word
})
replacedArray.join(" ") //'replace1 replace2 word word2'

edit: Since your data already exists in two arrays, you can build your own object out of them before running the replacement algorithm. You really need the O(1) lookup, so don't skip this.

const find = ['find1', 'find2', 'find3']
const replace = ['replace1', 'replace2', 'replace3']
findReplace = {}
for (let i = 0; i < find.length; i++) {
  findReplace[find[i]] = replace[i]
}

console.log(findReplace) //{ find1: 'replace1', find2: 'replace2', find3: 'replace3' }
Andrew
  • 7,201
  • 5
  • 25
  • 34
  • I just changed it slightly so the findReplace variable is hardcoded in, so that it doesn't have to form this every time the script loads, but this is a superb answer. The improvement in performance is very noticeable as compared to my previous iterative search and replace process. Thanks! – Rookie Oct 12 '17 at 14:19
  • Always happy to help. This algorithm is O(3n) -> O(n). Your original attempt is, at best, O(n^2). It will scale even better later on. – Andrew Oct 12 '17 at 17:58