ex-int-05-numbers/Numbers/NumberString/NumberString.cs
2025-05-10 22:58:56 +02:00

84 lines
2.6 KiB
C#

using System.Collections;
namespace Numbers.NumberString;
/// <summary>
/// Represents a string consisting of digits and letters intermixed
/// </summary>
/// <inheritdoc cref="IEnumerable{T}" />
/// <inheritdoc cref="IComparable{T}" />
public sealed class NumberString : IEnumerable<int>, IComparable<NumberString>
{
private readonly string _text;
private int? _numericValue;
/// <summary>
/// Creates a new instance of <see cref="NumberString" /> based on the given text.
/// As a simplification, the text is assumed to be a valid number string.
/// </summary>
/// <param name="text">A string containing digits and letters</param>
public NumberString(string text)
{
_text = text;
string digitsOnly = new string(text.Where(char.IsDigit).ToArray());
_numericValue = digitsOnly.Length > 0 ? int.Parse(digitsOnly) : 0;
}
/// <summary>
/// Gets the numeric value contained in the number string
/// </summary>
public int NumericValue => _numericValue ?? 0;
/// <summary>
/// Gets the digit at the given index.
/// If the index is out of range, -1 is returned.
/// </summary>
/// <param name="index">Digit index</param>
public int this[int index]
{
get
{
string numberString = _numericValue.HasValue ? _numericValue.Value.ToString() : string.Empty;
if (index < 0 || index >= numberString.Length || numberString == string.Empty)
{
return -1;
}
return GetDigit(numberString[index]);
static int GetDigit(char c) => c - '0';
}
}
public int CompareTo(NumberString? other)
{
if (ReferenceEquals(this, other))
{
return 1;
}
return NumericValue.CompareTo(other?.NumericValue);
}
public IEnumerator<int> GetEnumerator() => new DigitEnumerator(_text);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public override bool Equals(object? obj)
{
if (obj is not NumberString numberString)
{
return false;
}
return numberString._numericValue == _numericValue;
}
public override int GetHashCode() => _numericValue?.GetHashCode() ?? 0;
public static bool operator >(NumberString a, NumberString b) => a.CompareTo(b) > 0;
public static bool operator <(NumberString a, NumberString b) => a.CompareTo(b) < 0;
public static bool operator ==(NumberString a, NumberString b) => a?.Equals(b) ?? ReferenceEquals(b, null);
public static bool operator !=(NumberString a, NumberString b) => !(a == b);
}