0

my code is like that..

function replaceAll(str, from, to) {
  let result = ''
  for(let i = 0 ; i < str.length ; i++) 
  if(str[i]===from) {
       result = str.replace(from,to) 
     }
   }
   return result; 
 }

i wanna return like that

let output = replaceAll('loop', 'o', 'e');
console.log(output); // --> 'leep'

but it's only changed 'leop'

AL-zami
  • 8,902
  • 15
  • 71
  • 130
Loolii
  • 397
  • 3
  • 9
  • 2
    it is quite unclear, why you need a loop here. – Nina Scholz Jan 23 '21 at 14:15
  • 1
    @NinaScholz to deal with the fact that `replace(string, ...)` only replaces the first occurance of that string. But the entire construct is cumbersome and only works as long as `from.length === 1` – Thomas Jan 23 '21 at 14:23

6 Answers6

3

You can use replaceAll() function in JavaScript.

const str = 'loop';
console.log(str.replaceAll('o', 'e'));
Prime
  • 2,809
  • 1
  • 7
  • 23
3

You can solve your problem in two ways:

  • using replace function (supported by every browser) with the global modifier (/…/g) to replace all the occurrences
  • using replaceAll function (supported by Chrome 85+, Edge 85+, Firefox 77+, Opera 71+, Safari 13.1+; not supported by Internet Explorer)

let str = 'loop';
console.log(str.replace(/o/g, 'e'));
console.log(str.replaceAll('o', 'e'));
Alessio Cantarella
  • 5,077
  • 3
  • 27
  • 34
1

Why?

for simple replace only replace the first matching text. So you need to use g-Global text match mode. But you are passing from text as variable. so use RegExp to create regular expression like

RegExp(from,'g')

function replaceAll(str, from, to) {
  return str.replace(RegExp(from,'g'),to)
}

let output = replaceAll('loop', 'o', 'e');
console.log(output); // --> 'leep'
prasanth
  • 22,145
  • 4
  • 29
  • 53
  • 1
    With a construct like this you should always [escape special characters](https://stackoverflow.com/a/9310752/6567275) before passing the string to `RegExp`. – Thomas Jan 24 '21 at 08:40
1

It tells you why it doesn't work.

function replaceAll(str, from, to) {
            let result = str;
            for(let i = 0 ; i < str.length ; i++) {
                if(str[i]===from) {
                    result = result.replace(from,to);
                }
            }
            return result; 
        }
Harney
  • 352
  • 1
  • 4
1

If you really want to take a loop, you need to assign the replaced string to str instead to result, because you take the original str for replacing, but assigning to result.

String#replace replaces only the first find of the string. If you take a regular expression you could replace all occcurences directly.

function replaceAll(str, from, to) {
  for (let i = 0; i < str.length; i++) {
    if (str[i] === from) {
      str = str.replace(from, to);
    }
  }
  return str;
}


let output = replaceAll('loop', 'o', 'e');
console.log(output); // --> 'leep'
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
1

Let's dive deeper into your problem so that you can understand what is really going on here


function replaceAll(str, from, to) {
      let result = ''
          for(let i = 0 ; i < str.length ; i++) 
              if(str[i]===from) {
                  result = str.replace(from,to) 
              }
          }
      return result; 
}

str is a string type variable. String data-type is value type. When you change a character in a string it does not rewrite the content of the initial variable. It rather create a new string value and store it to memory.The previous value is garbage collected.

Initially str == loop, now if you change first 'o' with 'e' then str remains 'loop'. A new data is assigned to result variable which holds the value 'leop'. That is why in your for loop always same value is being assigned to result variable.

Let's visualize the process:


1st iteration : 
  result = 'loop'.replace('o','e') // leop
  // result is now 'leop' and str remains 'loop'

2nd iteration :
  result = 'loop'.replace('o','e') // leop
 // as str remained 'loop', so result will again be 'leop

That's why result variable remains the same after the for loop is completed.


Another thing to notice, although in 1st and 2nd iterations, value of result variable is same ('leop'), But in 2nd loop, initial 'leop' from first loop is gurbage collected (thrown away) in order to assign it another value (in our case another 'leop')

AL-zami
  • 8,902
  • 15
  • 71
  • 130