Thursday, September 27, 2018

Use .CompareTo in C# to compare two strings in two different lists while looping through each list only once!

private static List<Certificate> FilterCertificates(Bootstrapping bootstrapping)
{
   List<Certificate> filteredCertificates = new List<Certificate>();
   List<Certificate> certificates = bootstrapping.CertificateAuditing.Audit(bootstrapping)
         .OrderBy(x => x.Name).ToList();
   if (bootstrapping.CertificatesWhichMeritAttention.Length == 0) return certificates;
   int counter = 0;
   foreach (string certificateWhichMeritsAttention in
         bootstrapping.CertificatesWhichMeritAttention)
   {
      bool isVetted = false;
      while (!isVetted)
      {
         if (counter >= certificates.Count)
         {
            isVetted = true;
         }
         else
         {
            int comparison = certificates[counter].Name.ToLower()
                  .CompareTo(certificateWhichMeritsAttention.ToLower());
            if (comparison < 0)
            {
               counter++;
            }
            if (comparison == 0)
            {
               filteredCertificates.Add(certificates[counter]);
               counter++;
               isVetted = true;
            }
            if (comparison > 0)
            {
               isVetted = true;
            }
         }
      }
   }
   return filteredCertificates;
}

 
 

Per this the string comparison will compare each string a character at a time. Therefore, I think the .ToLower() stuff has to get mixed in as, as noted here, a lowercase a has a greater numeric ASCII code than a capital B which has a lower numeric ASCII code than a lowercase c. Clearly we could have just done this instead:

private static List<Certificate> FilterCertificates(Bootstrapping bootstrapping)
{
   List<Certificate> certificates = bootstrapping.CertificateAuditing
         .Audit(bootstrapping).OrderBy(x => x.Name).ToList();
   if (bootstrapping.CertificatesWhichMeritAttention.Length == 0) return certificates;
   List<Certificate> filteredCertificates = certificates.Where(x => bootstrapping
         .CertificatesWhichMeritAttention.Contains(x.Name)).ToList();
   return filteredCertificates;
}

 
 

Clearly that might make for more maintainable code. The big question is "Do we fear a performance hit (as suggested here) in a Big O puzzle?" as the shorter code will loop one of the lists once (perhaps not a full time, perhaps just until a match is made if a match is made) for every item in the other list and thus comes with more of a performance hit.

No comments:

Post a Comment