Lots to unpack here - can anyone explain how this works please?

This is one of the given solutions to the Intermediate Algorithm challenge Search and Replace:

String.prototype.capitalize =
  String.prototype.capitalize ||
  function() {
    return this[0].toUpperCase() + this.slice(1);
  };

const Util = (function() {
  function textCase(str, tCase) {
    if (tCase) {
      return setCase(str, tCase);
    } else {
      return getCase(str);
    }
function setCase(str, tCase) {
      switch (tCase) {
        case "uppercase":
          return str.toUpperCase();
        case "lowercase":
          return str.toLowerCase();
        case "capitalized":
          return str.capitalize();
        default:
          return str;
      }
    }

function getCase(str) {
      if (str === str.toUpperCase()) {
        return "uppercase";
      }
      if (str === str.toLowerCase()) {
        return "lowercase";
      }
      if (str === str.capitalize()) {
        return "capitalized";
      }
      return "normal";
    }
  }

  return {
    textCase
  };
})();

function myReplace(str, before, after) {
  const { textCase } = Util;
  const regex = new RegExp(before, "gi");
  const replacingStr = textCase(after, textCase(before));

  return str.replace(regex, replacingStr);
}

Iā€™m tearing my hair out a little trying to work out exactly how this code works. Can anyone explain it to me please? Many thanks!

(FWIW, my solution to this challenge is considerably shorter and simpler!)

Which part donā€™t you understand?

Iā€™ve edited your post for readability. When you enter a code block into a forum post, please precede it with a separate line of three backticks and follow it with a separate line of three backticks to make it easier to read.

You can also use the ā€œpreformatted textā€ tool in the editor (</>) to add backticks around text.

See this post to find the backtick on your keyboard.
Note: Backticks (`) are not single quotes (ā€™).

Thanks, I was wondering how to do that!

Ok, hereā€™s my limited understanding of whatā€™s going on:
You create a string method. Easy.
Then you create an IIFE, assigned to the variable Util.
I donā€™t understand the textCase function. How are the arguments str and tCase being supplied and how is tCase being assessed as true or false?
When that executes, it either invokes setCase or getCase.
The switch in setCase I donā€™t understand. I though that switch statements required breaks? I just donā€™t get how that makes a decision about which of the return commands to execute.
Where is the str argument getCase coming from? When it checks the status of str it returns the appropriate case label for the setCase function?
And what is return ā€œnormalā€? The string ā€œnormalā€ doesnā€™t appear anywhere else in the code.
What does return { textcase } do?

Ok, then you have the actual replace function itself.
const {textcase} = Util is an example of destructuring assignment? What does it do exactly?
The regex thing I understand.
Finally, replacingStr is the textCase function which passes after and then a nested version of itself which passes before?? I just donā€™t get how this works either.

My solution to the same challenge used a simple regex and ternary operator and the entire function is three lines of code. The solution above seems (to my novice coder brain) wildly over-engineered!

Hmmm, I have been searching for further info on this challenge solution (no.4) and came across this post, the author of which is less than impressed with the solution: Intermediate Algorithm Search And Replace needs to have solution replaced Ā· Issue #34761 Ā· freeCodeCamp/freeCodeCamp Ā· GitHub

FWIW, The final ā€˜solutionā€™ (no.5) provided in the guide is actually wrong and doesnā€™t even pass the challenge!

In fact, other provided solutions are also arguably inaccurate, in that they actually go beyond the criteria of the challenge, but donā€™t actually fail in any cases.

I donā€™t know that I would call a regex soultion simple for most beginners. I would agree that this one is pretty overenginered though.

Iā€™m not sure what you mean by ā€˜go beyond the criteriaā€™.

The criteria stipulate that the initial character of the replacing word should match the case of the initial character of the word being replaced. IIRC, a couple of the solutions iterate through the entire word, matching case of all characters.
My issue with these solutions is that they either go further than required, are so complex that they cover methods way beyond what has been already covered in the course, or that theyā€™re actually just plain wrong (i.e. no.4).
That said, Iā€™ve found solutions to other challenges to be really useful and instructive on the whole.
As for my solution, itā€™s about as basic as it gets and uses only methods which have been fully covered in the course. The regex /^[A-Z]/ is way simpler than many others covered in that section of the course.

Iā€™ll say again, most beginners do not find regex simple or easy to understand. Itā€™s cool that you like regex, but itā€™s a common source of confusion and frustration.

Yes, sure, I understand. I just figured that using a regex was an obvious approach as itā€™s a method which had been covered in considerable detail earlier in the course, thatā€™s all.
I certainly agree that regexes can be pretty confusing at times though!

1 Like

Ok, I think Iā€™ve almost got my head around this now.
The one thing I just donā€™t quite understand is:

return { textCase }

This creates an object with a single key/value pair (textCase: textCase) but I donā€™t understand exactly why itā€™s required? When const textCase is defined within the myReplace function, does that alone not allow you to call upon the textCase function within Util? Iā€™m sure itā€™s a really basic failure of understanding about how these things work but if someone could explain it to me, it would be really helpful!

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.