title: Compare two strings in JS of different lengths and mark matches greater than 3 characters in length
body: <p><strong>Tl;dr:</strong> I need to be able to compare two string of varying length, and pick out matches between them that are greater than 3 characters. As any matches greater than 3 characters are most likely full words. I'm working with angularJs, jQuery, and TypeScript if that's helpful to anyone.</p>
  
  <hr>
  
  <p>I need to be able to compare two strings, and note matches over 3 characters in length. This would be done on names, addresses, and email addresses. </p>
  
  <p>Basically the way the page works in this part of the web app is, there is a user who is suspected to be a duplicate account of another user. The suspected duplicate is flagged, and the web app user looks at the person flagged, and a list of people that may be the original account.</p>
  
  <p>Parts of the flagged user, and potential matches have their name, address, and email highlighted on words that match. To guide the web app user, so they can better see at a glance why specific people were pulled.</p>
  
  <p>For example if the flagged user had an email titled</p>
  
  <pre><code>JohnDoe1234@gmail.com
  </code></pre>
  
  <p>And potential match number one, of maybe 3, had an email titled</p>
  
  <pre><code>JohnathanDoe@yahoo.com
  </code></pre>
  
  <p>Then the words John, and Doe, should be highlighted, so the person deciding whether a flagged user is a dudplicate account or not can see at a glance that the flagged user simply created a new email with a shortened version of their first name. The emails closely match, the first name, and last name match, and the addresses are the same, they're a duplicate, deny their account.</p>
  
  <p>Undertaking this task, this is what I had written to work through this.</p>
  
  <pre><code>//populate flaggedStringArr with flaggedAssessor email
      stringPopPos = 0;
      for (var i: number = 0; i &lt; this.flaggedAssessor.email.length; i++) {
          flaggedStringArr.push(this.flaggedAssessor.email.charAt(stringPopPos));
          stringPopPos++;
      }
  
      //populate matchedStringArr with assessor email
      stringPopPos = 0;
      for (var i: number = 0; i &lt; this.assessor.email.length; i++) {
          matchedStringArr.push(this.assessor.email.charAt(stringPopPos));
          stringPopPos++;
      }
  
      //Determine which stringArr is longer for next loop
      if (flaggedStringArr &gt; matchedStringArr) {
          flaggedShortest = false;
      } else {
          flaggedShortest = true;
      }
  
      //compare the two string arrays. As matches are found store the letter that was matched in a new array.
      //As matches are found increment a counter. If 3 or more consecutive matches are found, then a possible word has been found and matched.
      //Loop duration is based off the shorter of the two string arrays
      for (var i: number = 0; i &lt; (flaggedShortest ? flaggedStringArr.length : matchedStringArr.length); i++) {
          if (flaggedStringArr[i] === matchedStringArr[i]) {
              storedChars.push(flaggedStringArr[i]);
              matchCounter++;
          } else {
              matchLog.push(matchCounter);
              matchCounter = 0;
          }
      }
  
      //matchLog has one entry that was not pushed because loop ends
      //push that entry
      matchLog.push(matchCounter);
  
      //Begin searching the match log for matches
      for (var i: number = 0; i &lt; matchLog.length; i++) {
          //search for matchLog values that are greater than 3
          //while searching if one of the logs values is not greater than 3, add it to a counter
          //when a match is found, use the counter to start assembling a string at the appropriate location
          if (matchLog[i] &gt; 3) {
  
              //a match has been found assemble a regex to search
              //use stringTraverse to know where to start in the storedChars array
              //use the value in the matchLog at position i to tell you how far along the string to go
              for (var ni: number = 0; ni &lt; (matchLog[i]); ni++) {
                  regExSearch += storedChars[stringTraverse + ni];
              }
              //The loop has constructed the string 
              //add the regex search term to the regexArr for later
              regexArr.push(regExSearch);
  
              //Empty regexSearch param for next match search
              regExSearch = '';
  
              //add matchLog's current value to string array in case there are future matches beyond this one
              stringTraverse += matchLog[i];
  
          } else {
              stringTraverse += matchLog[i];
          }
      }
      $('#emailToSwap').attr('id', `emailNumber${this.ownIndex}`);
      //Now out of the loop cycle through and apply styles to the regex search terms
      for (var i: number = 0; i &lt; regexArr.length; i++) {
          var regexObj: RegExp = new RegExp(regexArr[i], 'g');
          $(`#emailNumber${this.ownIndex}`).html(
              function (index, h) {
                  return h.replace(regexObj, `&lt;span class="dedupe-match"&gt;${regexArr[i]}&lt;/span&gt;`);
              }
          );
      }
  </code></pre>
  
  <p>Then I realized the problem is, this only works for strings of exactly the same length, so:</p>
  
  <p>JohnDoe@gmail.com</p>
  
  <p>and</p>
  
  <p>JohnRoe@gmail.com</p>
  
  <p>will match on John, and oe@gmail.com</p>
  
  <p>but if I offset either one by one letter i.e.</p>
  
  <p>JohnDoe@gmail.com</p>
  
  <p>and</p>
  
  <p>SJohnRoe@gmail.com</p>
  
  <p>now my code will match on absolutely nothing, because it compares one character at a time to another for each string. So now I'm at a loss for how to continue.</p>
  
  <p>I'm working with angularJs, jQuery, and Typescript if that's helpful information for anyone.</p>