Last active
February 26, 2026 00:46
-
-
Save karenpayneoregon/b0c9daeda4e7f0fea90ec2da31a02a9c to your computer and use it in GitHub Desktop.
NextValue multiple versions for teaching
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using System.Text.RegularExpressions; | |
| namespace TODO.Classes; | |
| public partial class Helpers | |
| { | |
| /// <summary> | |
| /// Generates the next value in a sequence by incrementing the numeric portion of the input string. | |
| /// </summary> | |
| /// <param name="sender"> | |
| /// The input string containing a numeric portion at the end. The numeric portion will be incremented. | |
| /// </param> | |
| /// <param name="incrementBy"> | |
| /// The value by which to increment the numeric portion of the input string. Defaults to 1. | |
| /// </param> | |
| /// <returns> | |
| /// A new string with the numeric portion incremented by the specified value, preserving the original length of the numeric portion. | |
| /// </returns> | |
| /// <exception cref="System.FormatException"> | |
| /// Thrown if the numeric portion of the input string cannot be parsed as a valid number. | |
| /// </exception> | |
| /// <exception cref="System.ArgumentNullException"> | |
| /// Thrown if the <paramref name="sender"/> is <c>null</c>. | |
| /// </exception> | |
| public static string NextValue(string sender, int incrementBy = 1) | |
| { | |
| string value = NumbersPattern().Match(sender).Value; | |
| return sender[..^value.Length] + (long.Parse(value) + incrementBy) | |
| .ToString().PadLeft(value.Length, '0'); | |
| } | |
| /// <summary> | |
| /// Updates the input string by incrementing the numeric portion at the end of the string. | |
| /// </summary> | |
| /// <param name="sender"> | |
| /// A reference to the input string containing a numeric portion at the end. | |
| /// The numeric portion will be incremented, and the updated string will be assigned back to this parameter. | |
| /// </param> | |
| /// <param name="incrementBy"> | |
| /// The value by which to increment the numeric portion of the input string. Defaults to 1. | |
| /// </param> | |
| /// <exception cref="System.FormatException"> | |
| /// Thrown if the numeric portion of the input string cannot be parsed as a valid number. | |
| /// </exception> | |
| /// <exception cref="System.ArgumentNullException"> | |
| /// Thrown if the <paramref name="sender"/> is <c>null</c>. | |
| /// </exception> | |
| public static void NextValue(ref string sender, int incrementBy = 1) | |
| { | |
| string value = NumbersPattern().Match(sender).Value; | |
| sender = sender[..^value.Length] + (long.Parse(value) + incrementBy) | |
| .ToString().PadLeft(value.Length, '0'); | |
| } | |
| /// <summary> | |
| /// Generates the next value in a sequence by incrementing the numeric portion of the input string, | |
| /// using a <see cref="System.ReadOnlySpan{T}"/> for optimized performance. | |
| /// </summary> | |
| /// <param name="sender"> | |
| /// The input string containing a numeric portion at the end. The numeric portion will be incremented. | |
| /// </param> | |
| /// <param name="incrementBy"> | |
| /// The value by which to increment the numeric portion of the input string. Defaults to 1. | |
| /// </param> | |
| /// <returns> | |
| /// A new string with the numeric portion incremented by the specified value, preserving the original length of the numeric portion. | |
| /// </returns> | |
| /// <exception cref="System.ArgumentNullException"> | |
| /// Thrown if the <paramref name="sender"/> is <c>null</c> or empty. | |
| /// </exception> | |
| public static string NextValueSpan(string sender, int incrementBy = 1) | |
| { | |
| if (string.IsNullOrEmpty(sender)) return sender; | |
| ReadOnlySpan<char> s = sender.AsSpan(); | |
| int intLength = s.Length - 1; | |
| while (intLength >= 0 && (uint)(s[intLength] - '0') <= 9) intLength--; | |
| int numberStart = intLength + 1; | |
| if (numberStart == s.Length) | |
| return sender; | |
| ReadOnlySpan<char> numberSpan = s[numberStart..]; | |
| long value = 0; | |
| foreach (char c in numberSpan) | |
| value = (value * 10) + (c - '0'); | |
| value += incrementBy; | |
| int width = numberSpan.Length; | |
| return string.Create(sender.Length, (sender, numberStart, value, width), static (dest, state) => | |
| { | |
| var (originalString, start, newValue, w) = state; | |
| originalString.AsSpan(0, start).CopyTo(dest); | |
| Span<char> suffix = dest.Slice(start); | |
| Span<char> fmt = stackalloc char[16]; | |
| int fmtLen = 0; | |
| fmt[fmtLen++] = 'D'; | |
| int temp = w; | |
| Span<char> digits = stackalloc char[10]; | |
| int dlen = 0; | |
| do | |
| { | |
| digits[dlen++] = (char)('0' + (temp % 10)); | |
| temp /= 10; | |
| } while (temp > 0); | |
| for (int k = dlen - 1; k >= 0; k--) | |
| fmt[fmtLen++] = digits[k]; | |
| if (!newValue.TryFormat(suffix, out _, fmt[..fmtLen], provider: null)) | |
| { | |
| newValue.ToString().AsSpan().CopyTo(suffix); | |
| } | |
| }); | |
| } | |
| /// <summary> | |
| /// Updates the input string by incrementing the numeric portion at the end of the string, | |
| /// using a <see cref="System.ReadOnlySpan{T}"/> for optimized performance. | |
| /// </summary> | |
| /// <param name="sender"> | |
| /// The input string containing a numeric portion at the end. The numeric portion will be incremented. | |
| /// </param> | |
| /// <param name="incrementBy"> | |
| /// The value by which to increment the numeric portion of the input string. Defaults to 1. | |
| /// </param> | |
| /// <exception cref="System.ArgumentNullException"> | |
| /// Thrown if the <paramref name="sender"/> is <c>null</c> or empty. | |
| /// </exception> | |
| public static void NextValueSpan(ref string sender, int incrementBy = 1) | |
| => sender = NextValueSpan(sender, incrementBy); | |
| [GeneratedRegex("[0-9]+$")] | |
| private static partial Regex NumbersPattern(); | |
| } | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment