This question is pretty much the opposite of this question: Does C# have built-in support for parsing page-number strings?
So given
1,3,5,6,7,8,9,10
When something has several moving parts like this, I think it helps to decompose it into little logical units and then combine them together. The little logical units might even be usable separately. The code below breaks the problem down into:
The program is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication37 {
public static class Program {
static void Main(string[] args) {
var numList=new[] {1, 3, 5, 6, 7, 8, 9, 10, 12};
Console.WriteLine(numListToPossiblyDegenerateRanges(numList).Select(r => PrettyRange(r)).Intersperse(","));
}
///
/// e.g. 1,3,5,6,7,8,9,10,12
/// becomes
/// (1,1),(3,3),(5,10),(12,12)
///
public static IEnumerable> numListToPossiblyDegenerateRanges(IEnumerable numList) {
Tuple currentRange=null;
foreach(var num in numList) {
if(currentRange==null) {
currentRange=Tuple.Create(num, num);
} else if(currentRange.Item2==num-1) {
currentRange=Tuple.Create(currentRange.Item1, num);
} else {
yield return currentRange;
currentRange=Tuple.Create(num, num);
}
}
if(currentRange!=null) {
yield return currentRange;
}
}
///
/// e.g. (1,1) becomes "1"
/// (1,3) becomes "1-3"
///
///
///
public static string PrettyRange(Tuple range) {
if(range.Item1==range.Item2) {
return range.Item1.ToString();
}
return string.Format("{0}-{1}", range.Item1, range.Item2);
}
public static string Intersperse(this IEnumerable items, string interspersand) {
var currentInterspersand="";
var result=new StringBuilder();
foreach(var item in items) {
result.Append(currentInterspersand);
result.Append(item);
currentInterspersand=interspersand;
}
return result.ToString();
}
}
}