Convert list to number range string

后端 未结 6 629
你的背包
你的背包 2020-12-05 19:45

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         


        
6条回答
  •  情书的邮戳
    2020-12-05 20:49

    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:

    • turning the heterogeneous set of sequential and nonsequential numbers into a homogenous set of ranges (possibly including "degenerate" ranges which start and end at the same number)
    • a way to "pretty-print" such ranges: (x,y) prints as "x-y"; (x,x) prints as "x"
    • a way to interperse a separator between elements of an enumerable, and convert the result into a string.

    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();
        }
      }
    }
    

提交回复
热议问题