I have a string like string x = "AB001-AB050, AB055, AB060-AB099".
I am looking for a solution to get all the values in this range.
The output should contain all values between AB001
and AB050
, then AB055
and then all values between AB060
and AB099
.
Additional details: The 2 first char are only letters. The 3 last char are only numbers.
Example : given AB008 - AB012, AB020 Expected o/p : AB008, AB009, AB010,AB011, AB012,AB020
If you need no increment the Letter too here is a solution base on the link and the existing answer.
Base 26 -> 10 convertion :
Based on Quickest way to convert a base 10 number to any base in .NET?
private static readonly char[] BaseChars =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ".ToCharArray();
private static readonly Dictionary<char, int> CharValues = BaseChars
.Select((c, i) => new { Char = c, Index = i })
.ToDictionary(c => c.Char, c => c.Index);
public static string LongToBase(long value)
{
long targetBase = BaseChars.Length;
// Determine exact number of characters to use.
char[] buffer = new char[Math.Max(
(int)Math.Ceiling(Math.Log(value + 1, targetBase)), 1)];
var i = buffer.Length;
do
{
buffer[--i] = BaseChars[value % targetBase];
value = value / targetBase;
}
while (value > 0);
return new string(buffer, i, buffer.Length - i);
}
public static long BaseToLong(string number)
{
char[] chrs = number.ToCharArray();
int m = chrs.Length - 1;
int n = BaseChars.Length, x;
long result = 0;
for (int i = 0; i < chrs.Length; i++)
{
x = CharValues[chrs[i]];
result += x * (long)Math.Pow(n, m--);
}
return result;
}
Parsing the input :
Based on Dervis answer
var ranges = valuePart.Split(',')
.Select(x => {
var range = x.Split('-')
.Select(x=> x.Trim()) // only thing I typed
.ToList();
if (range.Count() > 1)
return RangeLong(BaseToLong(range[0]), BaseToLong(range[1]) - BaseToLong(range[0]) + 1);
return RangeLong(BaseToLong(range[0]), 1);
});
var result = ranges.SelectMany(x => x.Select(y=> LongToBase(y))).ToList();
Simple implementation of Enumerable range for long : Based on https://referencesource.microsoft.com/#System.Core/System/Linq/Enumerable.cs,1271
static IEnumerable<long> RangeLong(long start, long count)
{
for (long i = 0; i < count; i++) yield return start + i;
}
This code was build only using copypast from code and ressource linked on this very question, only .Select(x=> x.Trim())
was typed