场景:数据库有包含帐号列表的表。帐号范围为 0-9999。允许客户在他们认为合适的情况下为该范围内的客户制作帐号。
需要:我正在生成一份报告,以范围格式显示未使用的帐号。所以,我需要一个字符串列表,以范围格式显示可用的帐号。
示例:帐号 0、1、2、4、20、21、22 都在数据中使用。所以结果列表将是......
3
5-19
23-9999
整天在这上面磕磕绊绊。如何使用直接的 c# 来做到这一点?
场景:数据库有包含帐号列表的表。帐号范围为 0-9999。允许客户在他们认为合适的情况下为该范围内的客户制作帐号。
需要:我正在生成一份报告,以范围格式显示未使用的帐号。所以,我需要一个字符串列表,以范围格式显示可用的帐号。
示例:帐号 0、1、2、4、20、21、22 都在数据中使用。所以结果列表将是......
3
5-19
23-9999
整天在这上面磕磕绊绊。如何使用直接的 c# 来做到这一点?
var acctNos = new List<int>() { 0,1,2,4,20,21,22 };
var unusedAcctNos = Enumerable.Range(0,9999).ToList().Except(acctNos);
然后对连续整数进行分组,修改此处给出的可接受的解决方案。
根据您获取帐户数据的方式,例如:
var nums = Enumerable.Range(0, 9999).ToList();
var usedNums = new List<int> {0, 1, 2, 3, 4, 20, 21, 22};
var availableNums = nums.Except(usedNums);
这将为您提供可用整数的 IEnumerable。然后,将它们格式化为“3、5-19、23-99”需要额外的逻辑。
//assuming already sorted
var a = Enumerable.Range(0, 10000);
//assuming alredy sorted
var b = new List<int>(){0, 1, 2, 4, 20, 21, 22};
//get the values not used yet in sorted order
var c = a.Except(b).ToList();
//store the list range
List<string> range = new List<string>();
for(int i = 0; i < c.Count; i++)
{
//current start range
int current = c[i];
string r = current.ToString();
int next;
if(current > b.Last())
next = c.Last() + 1;
else
next = b.FirstOrDefault( x => x > current);
if( next != current+1)
r += "-" + (next-1).ToString();
range.Add(r);
while(c[i] < next-1) i++;
}
大型解决方案:)
static List<string> getAvailablesRanges(List<int> data,int maxrange)
{
List<string> ranges = new List<string>();
string last = null;
foreach (int i in data)
{
if (i == data.Max() && i != maxrange)
{
if (last != null) ranges.Add(last + "-" + i);
ranges.Add(i + "-" + maxrange);
}
else if (last == null)
last = i.ToString();
else
{
if(i-int.Parse(last)>1) ranges.Add(last + "-" + i);
last = null;
}
}
return ranges;
}
bool[] accountNumbers = new bool[10000];
for(int accountNumber in collection){
accountNumbers[accountNumber] = true;
}
string available = '';
for(int i = 0; i < accountNumbers.length; ++i){
if(!accountNumbers[i]) available += (i + ',');
}
available = available.substring(0, available.length-2);
你必须在我刚写的时候测试它(使用 joshes 解决方案来获取列表)
var acctNos = new List<int>() { 0,1,2,4,20,21,22 };
var unusedAcctNos = Enumerable.Range(0, 10000).Except(acctNos).ToList();
StringBuilder builder = new StringBuilder();
int lastNo = unusedAcctNos.Last();
int previousVal = -2;
bool isRange = false;
foreach (int i in unusedAcctNos)
{
if (i == previousVal + 1 && i != lastNo) //is in range
{
previousVal = i;
isRange = true;
continue;
}
else if (previousVal > -1) //range broke
{
if (isRange)
{
builder.Append("-");
if (i == lastNo && previousVal == i - 1)
{
builder.Append(i);
break;
}
else
{
builder.Append(previousVal);
}
isRange = false;
}
builder.Append(",");//change group splitter here
}
builder.Append(i);
previousVal = i;
}