2
\$\begingroup\$

while doing a code clash on codingames, in which we had to replace a character in a string one by one to transform it into a target string, printing out every itteration of the new string, resulting in something like this:

"Turtle Ham"
"Hurtle Ham"
"Hartle Ham"
"Hamtle Ham"
"Ham le Ham"
"Ham Me Ham"
"Ham Ma Ham"
"Ham MakHam"
"Ham Makeam"
"Ham Makerm"
"Ham Maker!"

This is de code I came up with, in Javascript.

var source = "Turtle Ham";
var target = "Ham Maker!";
var safe = source;
String.prototype.replaceAt=function(index, character) {
    return this.substr(0, index) + character + this.substr(index+character.length);
}
console.log(source);
for(var i=0; i < source.length; i++) {
    source = source.replaceAt(i, target.charAt(i));
    if(source == safe) {
        
    } else {
     console.log(source);
     safe = source;
    }
}

would there be any more effective way of doing this in Javascript?

\$\endgroup\$
6
  • 1
    \$\begingroup\$ I guess I'll +1 this even though you did it in a linear order. It would be cool to see this randomized so that it's not just char 0, then 1, etc. \$\endgroup\$ – Der Kommissar Dec 15 '16 at 8:21
  • \$\begingroup\$ @EBrown yea it would've been cool to see that indeed, though I'd have no clue on how to do that atm :P \$\endgroup\$ – Grey Dec 15 '16 at 8:22
  • 1
    \$\begingroup\$ Hint: generate an array of source.length, then fill each position with a random number from 0 to source.length - 1, then enumerate that array instead and replace the char at array[i] position instead of i position. ;) \$\endgroup\$ – Der Kommissar Dec 15 '16 at 8:23
  • \$\begingroup\$ oh yea, that's actually quite nice and simple, will remind that for when I ever wanna use this to transform a randomly transforming string as a visual effect on a website :D \$\endgroup\$ – Grey Dec 15 '16 at 8:26
  • 1
    \$\begingroup\$ Instead of: if(source == safe) {} else {... Just if(source != safe) {.... \$\endgroup\$ – tmp Dec 15 '16 at 10:30
1
\$\begingroup\$
  • As Tyler Flynn pointed out in a comment, you should flip the conditional from "equals" to "not equals" to avoid the (current empty) if branch:

    if(source != safe) {
      console.log(source);
      safe = source;
    }
    
  • I'd avoid extending the String prototype. The method you're adding is pretty generic, and could be reusable, so it's not a terrible thing to add, but still. Extending prototypes is generally considered bad form - not because it'll instantly break anything, but rather because if everybody did it, they might defined replaceAt in some other way, and break your code. Or your extension would break their code. So extending prototypes, while often tempting, should be considered carefully.
    In this case, it'd be just as simple to have a replaceAt(string, index, character) function that you call with the string, instead of calling it on the string.

Other than that, you code seems OK. There are a ton of other approaches you could take, of course, but without some external metric to judge by, yours is as good as any other.

However, there's one issue which irks me a little: source is mutated. With your current code, you can't print the original string after the loop has run, because you've "lost" it - source just becomes equal to target. I'd keep source and target unaltered, and generate a third "result" string for each step instead.

This also points to an alternative approach: Instead of replacing characters, create a new string by glueing parts of the two others together.

var source = "Turtle Ham";
var target = "Ham Maker!";

var lastResult = null;

for(var i = 0; i <= source.length ; i++) {
  var result = target.substr(0, i) + source.substr(i);

  if(result != lastResult) {
    console.log(result);
  }

  lastResult = result;
}

This code doesn't even need a separate function or prototype extension, and doesn't mutate the input (source and target) strings. It also doesn't need an extra console.log to show the original; everything happens in the loop, which runs from 0 characters replaced to source.length (inclusive) characters replaced.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.