4
\$\begingroup\$

I have a collection of strings as follows:

44.01
44.02
44.03
44.04
44.12
46.05
46

... and so on.

I want to remove leading zeros from the component of the string after the full stop.

As you can see from above, not all strings have a sub-component and not all sub-components will have leading zeros.

Is there a more elegant way of doing that from my attempt?

    List<string> codesWithSubCodes = new List<string>
    {
        "44.01", "44.02", "44.03", "44.04", "44.05", "44.06", "44.07", "44.08"
    };

    var codes = new List<string>();
    foreach (var code in codesWithSubCodes)
    {
        if (code.Contains('.'))
        {
            var prefix = code.Split('.')[0];
            var subCode = code.Split('.')[1].TrimStart('0');
            codes.Add(prefix + '.' + subCode);
        }
        else
        {
            codes.Add(code);
        }
    }

    foreach (var code in codes)
    {
        Debug.WriteLine(code);
    }
\$\endgroup\$
  • \$\begingroup\$ Are you trying to turn them into numbers? \$\endgroup\$ – 410_Gone Jul 8 '15 at 17:14
  • \$\begingroup\$ No, they will always remain as strings. \$\endgroup\$ – Ciaran Gallagher Jul 8 '15 at 17:15
  • \$\begingroup\$ Is there ever more than 1 0? (46.002) \$\endgroup\$ – 410_Gone Jul 8 '15 at 17:17
  • \$\begingroup\$ No, the second component of each string (if there is a 2nd component) will always have 2 characters. \$\endgroup\$ – Ciaran Gallagher Jul 8 '15 at 17:20
  • \$\begingroup\$ In that case, I just recommended two methods that could help you out. \$\endgroup\$ – 410_Gone Jul 8 '15 at 17:31
8
\$\begingroup\$

The biggest thing I can see, which may or may not be an issue, is the manner in which you process the strings.

    if (code.Contains('.'))
    {
        var prefix = code.Split('.')[0];
        var subCode = code.Split('.')[1].TrimStart('0');
        codes.Add(prefix + '.' + subCode);
    }
    else
    {
        codes.Add(code);
    }

This could be rewritten as:

var codeSections = code.Split('.');
var code = codeSections[0];

if (codeSections.Length == 2)
    code += "." + codeSections[1].TrimStart('0');

codes.Add(code);

This saves you LoC, and probably makes it faster. (You could also possible make this a StringBuilder as well.) And in my opinion, this is more readable/concise/descriptive.

Another alternative:

code = code.Replace(".0", ".");

Both should have the same effect on the cases you provided.

However, if, for whatever reason, one of the cases ends up as 46.00, then the second method will only make it 46.0. Choose that method with great caution.

As the OP pointed out in an edit that should have been a comment, this code can all be done as LINQ:

var codes = codesWithSubCodes.ConvertAll(code => code.Replace(".0", "."));
\$\endgroup\$
4
\$\begingroup\$

If you want to remove any number of leading zeros from the second component of your string then you can do:

var query = codesWithSubCodes.Select(r=> new
            {
                SplitResult = r.Split('.'),
                OriginalValue = r
            })
            .Select(r=> 
            r.SplitResult.Length == 2 ? 
            r.SplitResult.First() + "." + r.SplitResult.Last().TrimStart('0')
            : r.OriginalValue
            );

This is how this query works:

  • First Split the string on delimiter and store it temporarily so that you don't have to do Split multiple times
  • Later it checks if the result of Split is a 2 element array then return concatenation of first element , delimiter and last element with removing all the 0s from the beginning.
  • If the Split results in length not being 2, then return the original element.

With respect to your code, you can improve following thing:

  • Do not check for delimiter Contains, instead Split the string and check length. That way you only Split the element once.

So the iteration part could look like:

foreach (var code in codesWithSubCodes)
{
    string[] SplitResult = code.Split('.');
    if (SplitResult.Length == 2)
    {
        var prefix = SplitResult[0];
        var subCode = SplitResult[1].TrimStart('0');
        codes.Add(prefix + '.' + subCode);
    }
    else
    {
        codes.Add(code);
    }
}

If you are always going to have a single zero after the . then you can use this simple LINQ query:

var codes = codesWithSubCodes.Select(r => r.Replace(".0", ".")).ToList();
\$\endgroup\$
  • 1
    \$\begingroup\$ This is a very intriguing answer, I never thought to use LINQ like that for this one. \$\endgroup\$ – 410_Gone Jul 9 '15 at 14:03

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.