如何获取给定字母数字范围内的所有值

问题描述

我有一个字符串,例如字符串x =“ AB001-AB050,AB055,AB060-AB099”。

我正在寻找一种解决方案,以获取此范围内的所有值。

输出应包含AB001AB050间的所有值,然后是AB055,然后是AB060AB099间的所有值。

其他详细信息:前两个字符只是字母。最后3个字符只是数字。

示例:给定AB008-AB012,AB020 预期o / p:AB008,AB009,AB010,AB011,AB012,AB020

解决方法

您是否正在寻找类似的东西?

var prefix = "AB";
var x = "AB001-AB050,AB055,AB060-AB099";

var lean_x = x.Replace(prefix,"");

var ranges = lean_x.Split(',').Select(x =>
{
    var  interval = x.Split('-').Select(x => Convert.ToInt32(x)).ToArray();
    if (interval.Count() > 1)
        return Enumerable.Range(interval[0],interval[1] - interval[0] + 1);
        
    return Enumerable.Range(interval[0],1);
}).SelectMany(p => p,(p,q) =>String.Format("{0}{1:000}",prefix,q));


ranges.Dump();
,

如果不需要增加字母,这也是基于链接和现有答案的解决方案。

以26为基础-> 10转换:
基于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;
}

解析输入:
基于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();
        

Enumerable range的简单实现很长时间: 基于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;
}
    

Live demo

此代码仅使用复制自此问题的代码和资源来构建,此问题仅链接.Select(x=> x.Trim())