2
\$\begingroup\$

I am trying to remove a duplicate letter of first or last letter, with an exception of containing 'a' as first letter and 'l' and 'e' as last letter. However, this code does not look efficient to me because, what if I had 20 letters of exception? Could I put this in a string or an array? I would not want to compare each letter all in one if statement. What would be a better way to rewrite this code? Example of what the code should do:

  • aaron should return aaron
  • bill should return bill
  • lee should return lee

All other names with duplicate first and last letters should return with the removed duplicate letter. This is a unit test, where firstName is being passed as a string. Instead of using if statement of each letter to check, is there an alternative solution?

UnitTest:

[TestCase("aaron", "aaron")]
public void QualityAssurance(string firstName, string expected)
{
    var actual = warmups.QualityAssurance(firstName);
    Assert.AreEqual(expected, actual);
}

Unit:

public string QualityAssurance(string firstName)
{
    if (firstName[0] != 'a' && firstName[firstName.Length - 1] != 'l' && firstName[firstName.Length - 1] != 'e')
    {
        if (firstName[0] == firstName[1] && firstName[firstName.Length - 1] == firstName[firstName.Length - 2])
        {
            return firstName.Remove(0, 1).Remove(firstName.Length - 2, 1);
        }
        else if (firstName[0] == firstName[1])
        {
            return firstName.Remove(0, 1);
        }
        else if (firstName[firstName.Length - 1] == firstName[firstName.Length - 2])
        {
            return firstName.Remove(firstName.Length - 1);
        }
    }
    return firstName;
}
\$\endgroup\$
  • 1
    \$\begingroup\$ This is exactly the same quesiton as before and it lacks context in exactly the same way so I'm voting to close it again... Why don't you just post the rest of the code as asked? – \$\endgroup\$ – t3chb0t May 24 '19 at 6:07
  • 1
    \$\begingroup\$ I posted the code \$\endgroup\$ – Alejandro H May 24 '19 at 15:04
  • \$\begingroup\$ Great! Thanks for updating! Now it looks like a question ;-) \$\endgroup\$ – t3chb0t May 24 '19 at 15:12
3
\$\begingroup\$

You're checking both the start and end twice and you only modify when both start and end have duplicate letters. Is that intentionally?:

  if (firstName[0] != 'a' && firstName[firstName.Length - 1] != 'l' && firstName[firstName.Length - 1] != 'e')
  {
    if (firstName[0] == firstName[1] && firstName[firstName.Length - 1] == firstName[firstName.Length - 2])
    {
      return firstName.Remove(0, 1).Remove(firstName.Length - 2, 1);
    }
    else if (firstName[0] == firstName[1])
    {
      return firstName.Remove(0, 1);
    }
    else if (firstName[firstName.Length - 1] == firstName[firstName.Length - 2])
    {
      return firstName.Remove(firstName.Length - 1);
    }
  }

It could be simplified to:

  if (string.IsNullOrEmpty(name) || name.Length < 2) return name;

  if (name[0] != 'a' && name[name.Length - 1] != 'l' && name[name.Length - 1] != 'e')
  {
    if (name[0] == name[1])
      name = name.Substring(1);
    if (name.Length > 1 && name[name.Length - 1] == name[name.Length - 2])
      name = name.Substring(0, name.Length - 1);
  }
  return name;

But what about "aaronn" shouldn't the last "nn" be reduced to one 'n' in that?

If so, you'll have to check start and end separately:

string RemoveDuplicatesAtStartAndEnd(string name)
{
  if (string.IsNullOrEmpty(name) || name.Length < 2) return name;

  if (name[0] != 'a' && name[0] == name[1])
    name = name.Substring(1);
  if (name.Length > 1 && name[name.Length - 1] != 'l' && name[name.Length - 1] != 'e' && name[name.Length - 1] == name[name.Length - 2])
    name = name.Substring(0, name.Length - 1);

  return name;
}

and as shown, you'll also have to validate the input before handling it.


If you want to handle any number of duplicates chars at start and end you can do:

string RemoveDuplicatesAtStartAndEnd(string name)
{
  if (string.IsNullOrEmpty(name) || name.Length < 2) return name;

  while (name.Length > 1 && name[0] != 'a' && name[0] == name[1])
    name = name.Substring(1);

  while (name.Length > 1 && name[name.Length - 1] != 'l' && name[name.Length - 1] != 'e' && name[name.Length - 1] == name[name.Length - 2])
    name = name.Substring(0, name.Length - 1);

  return name;
}

Another way could be to use Regex:

string RemoveDuplicatesAtStartAndEnd(string name)
{
  name = Regex.Replace(name, @"^([^a])\1{1,}", m => m.Value[0].ToString());
  return Regex.Replace(name, @"([^el])\1{1,}$", m => m.Value[0].ToString());
}

Other regex approaches may be valid, but this is one way to do it.


What about upper-lower case?


Your purpose for this method is not clear, but I wouldn't be confident about it, taken all possible names into account. Manipulate names in this way seems as risky business IMO.

\$\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.