# Zero pad function trim extra leading zeros

Here is a zero pad function I have:

''' <summary>
''' Take a number string and zero pad it to the specified length.
''' </summary>
''' <param name="Number">The string representation of the value that will be zero-padded.</param>
''' <param name="ToLength">The length of the string that will result after the zero-padding.</param>
''' <param name="TrimExtraZeroes">An optional boolean which, when true, indicates that any
''' extra leading zeroes that make the string longer than the desired length should be removed.</param>
''' <returns>A value which is the same as <paramref name="Number" /> but zero padded to the length specified by <paramref name="ToLength" />.</returns>
''' <remarks></remarks>
Friend Function ZeroPad(ByVal Number As String, ByVal ToLength As Integer, Optional ByVal TrimExtraZeroes As Boolean = False) As String
Const ZeroChar = "0"c

Select Case Number.Length
Case Is < ToLength
Return New String(ZeroChar, ToLength - Number.Length) & Number
Case Is = ToLength
Return Number
Case Is > ToLength
ZeroPad = Number

If (TrimExtraZeroes) Then
Do While ZeroPad.StartsWith(ZeroChar) AndAlso ZeroPad.Length > ToLength
ZeroPad = ZeroPad.Substring(1)
Loop
End If
Case Else
'This case can never occur, but it's here to suppress compiler warning.
Throw New InvalidOperationException(String.Format("Unknown number length: {0}", Number.Length))
End Select
End Function


Now, focusing on just one portion of it -- the part that trims leading zeros:

Do While ZeroPad.StartsWith(ZeroChar) AndAlso ZeroPad.Length > ToLength
ZeroPad = ZeroPad.Substring(1)
Loop


is there a more efficient, cleaner, or "slick" way to do this other than looping?

• Why is Number a String? I would recommend you store all numbers as their proper type (int, double) and convert them to string only when displaying them on screen. This would simplify your function a lot. – the_lotus Jan 9 '15 at 14:54
• @the_lotus -- I wrote this function a long time ago originally to zero-pad client and matter "numbers" in software I write for the law firm where I work. A client or matter "number" can actually have alphabetical characters, e.g. "045CN". I agree that it's improperly named, but I use it out of an old code snippet that I've never revisited. I'll probably change it to "numericalTextValue" or something like that. – rory.ap Jan 9 '15 at 14:59

## 3 Answers

Naming

Based on the naming guidelines parameters should be named using camelCase casing.

Select Case

If you omitt the Case Is > ToLength and the else part aka having only 2 cases you will have

Friend Function ZeroPad(ByVal Number As String, ByVal ToLength As Integer, Optional ByVal TrimExtraZeroes As Boolean = False) As String
Const ZeroChar = "0"c

Select Case Number.Length
Case Is < ToLength
Return New String(ZeroChar, ToLength - Number.Length) & Number
Case Is = ToLength
Return Number
End Select

If (TrimExtraZeroes) Then
Do While Number.StartsWith(ZeroChar) AndAlso Number.Length > ToLength
Number = Number.Substring(1)
Loop
End If
Return Number
End Function


Why don't you use the built in String.PadLeft() method which would obsolete the Select Case. In addition to first stripping any 0 of the left side of Number you won't need the loop at all.

This boils down to only this

Friend Function ZeroPad(ByVal Number As String, ByVal ToLength As Integer, Optional ByVal TrimExtraZeroes As Boolean = False) As String
Const ZeroChar = "0"c
If (TrimExtraZeroes) Then
Number = Number.TrimStart({ZeroChar})
End If
Return Number.PadLeft(ToLength, ZeroChar)
End Function


Update
Some timetables for calling both methods 1.000.000 times

                                    Yours(ms)  Mine(ms)
ZeroPad("0000000001", 2, False)       227       231
ZeroPad("0000000001", 2, True)       1696       297
ZeroPad("01", 2, False)               251       235
ZeroPad("01", 2, True)                248       263
ZeroPad("01", 12, False)              256       247
ZeroPad("01", 12, True)               257       260

• Interesting data, that it's faster to trim all the leading zeros first and build it back up. – rory.ap Jan 9 '15 at 15:07

So, what does this function do again? Does it leftpad a number with zeros, or does it strip them away? It does both and that breaks the single responsibility principle. Kind of...

You could rename it FormatString and then its name would reflect it's one responsibility. The only problem with that is we already have String.Format, but I'll get back to that. First, I want to talk about this.

ByVal Number As String


Number. As. String.

Let that sink in for a second. You're passing a Number into your function as a String. If that doesn't smell funny, I'm not quite sure what does. In fact, your function doesn't care at all if what it's padding is a number or not.

Console.WriteLine(ZeroPad("HelloWorld",20))
' 0000000000HelloWorld


I'm not sure if that's expected behavior or not, but I'm not sure it matters. I don't really think you need a special function to accomplish what you're doing. Just take your number and Format it. If the data is coming in as a string, then simply cast it to a value first.

Dim originalValue As String = "01234"
Dim newValue As Integer

If Int32.TryParse(originalValue, newValue) Then
Dim finalValue As String
finalValue = newValue.ToString("0000000000")

Console.WriteLine(finalValue)
End If


If TryParse fails, you could return the original string. If you don't want the original value if it's not a number, you could use Convert.ToInt32 and catch the appropriate exceptions.

TL;DR I don't think you need to do this at all. Sorry.

It just occured to me that you might not want to repeat this code each time you need to pad to a different length, so you could wrap it in a function like this. (Even though I still hate passing in a number as a string.)

Friend Shared Function ZeroPad(ByVal Number As String, ByVal ToLength As Integer)
Dim value As Integer

If Int32.TryParse(Number, value) Then
Return value.ToString(new String("0", ToLength))
Else
Return Number
End If
End Function


IDEOne here

You can loop and count the characters until zeropad.charAt(count) isn't ZeroChar or the remaining length is equal to the desired length and then take the substring(count) to return

• That would trim all leading ZeroChar characters instead of just the number that makes the length equal to Tolength. If that were what I wanted to do, I'd just use ZeroPad.TrimStart(ZeroChar). – rory.ap Jan 8 '15 at 17:15