使用此帮助程序类在数字列表和范围字符串之间来回转换。
这复制了ConvertRangeStringToNumberList()
从这里和ConvertNumberListToRangeString()
从这里的实现,并略有改进。
using System;
using System.Collections.Generic;
using System.Linq;
public static class NumberRangeHelper
{
/// <summary>
/// Converts a string of comma separated list of numbers and ranges to the list of individual numbers it represents.
/// </summary>
/// <param name="numbers">Range in form of <c>"2,4-8,11,15-22,39"</c></param>
/// <returns>A list of numbers</returns>
public static List<int> ConvertRangeStringToNumberList(string numbers)
{
var numbersSplit = numbers.Split(',');
var convertedNumbers = new SortedSet<int>();
foreach (var strNumber in numbersSplit)
{
int number;
if (int.TryParse(strNumber, out number))
{
convertedNumbers.Add(number);
}
else
{
// try and delimited by range
if (strNumber.Contains('-'))
{
var splitRange = strNumber.Split('-');
if (splitRange.Length == 2)
{
int firstNumber;
int secondNumber;
if (Int32.TryParse(splitRange[0], out firstNumber) &&
Int32.TryParse(splitRange[1], out secondNumber))
{
for (var i = firstNumber; i <= secondNumber; ++i)
{
convertedNumbers.Add(i);
}
}
}
}
}
}
return convertedNumbers.ToList();
}
/// <summary>
/// Converts a list of numbers to their concise range representation.
/// </summary>
/// <param name="numbers">A list of numbers such as <c>new[] { 1, 2, 3, 4, 5, 12, 13, 14, 19 }</c></param>
/// <returns>A string like <c>"1-5, 12-14, 19"</c></returns>
public static string ConvertNumberListToRangeString(IEnumerable<int> numbers)
{
var items = new SortedSet<int>(numbers)
.Select((n, i) => new { number = n, group = n - i })
.GroupBy(n => n.group)
.Select(g => (g.Count() >= 3)
? g.First().number + "-" + g.Last().number
: String.Join(", ", g.Select(x => x.number))
)
.ToList();
return String.Join(", ", items);
}
}
测试:
Action<IEnumerable<int>> DumpList = l => Console.WriteLine("\t[{0}]", String.Join(", ", l));
Action<string> DumpRange = s => Console.WriteLine("\t\"{0}\"", s);
var numbers = new[] { 1, 1, 2, 3, 4, 5, 12, 13, 19, 19, 6, 7 };
DumpList(numbers);
var str = ConvertNumberListToRangeString(numbers);
DumpRange(str);
var list = ConvertRangeStringToNumberList(str);
DumpList(list);
Console.WriteLine();
str = "1-5, 12, 13, 19, 20, 21, 2-7";
DumpRange(str);
list = ConvertRangeStringToNumberList(str);
DumpList(list);
str = ConvertNumberListToRangeString(list);
DumpRange(str);
输出:
[1, 1, 2, 3, 4, 5, 12, 13, 19, 19, 6, 7]
"1-7, 12, 13, 19"
[1, 2, 3, 4, 5, 6, 7, 12, 13, 19]
"1-5, 12, 13, 19, 20, 21, 2-7"
[1, 2, 3, 4, 5, 6, 7, 12, 13, 19, 20, 21]
"1-7, 12, 13, 19-21"