使用字符串表示法的SortedList,但按数字排序

问题描述

我注意到键int的排序列表对值进行数字排序

SortedList < int,double> sl0 = new SortedList<int,double>();
for(int i = 0; i < 20; i++)
  sl0.Add(i,0.01);

[0,0.01]
[1,0.01]
[2,0.01]
[3,0.01]
[4,0.01]
[5,0.01]
[6,0.01]
[7,0.01]
[8,0.01]
[9,0.01]
[10,0.01]
[11,0.01]
[12,0.01]
[13,0.01]
[14,0.01]
[15,0.01]
[16,0.01]
[17,0.01]
[18,0.01]
[19,0.01]

和键字符串的排序列表按字母顺序对值进行排序

SortedList < string,double> sl1 = new SortedList<string,double>();
for(int i = 0; i < 20; i++)
  sl1.Add(i.ToString(),0.01]

有什么办法可以使嵌套键按数字进行排序,例如,键的顺序必须像这样。首先,我想像我可以使用这样的字符串,但是可以确定它们是按字母顺序排序的:

//Keys
//"0;0"
//"0;0;0"
//"0;1"
//"0;2"
//"0;10"
//"0;10;1;0;0"
//"1;0"
//"2;1"
//"3;1"
//"3;1;2"

现在我有一个继承排序列表的类:

public class Plates : Comparer<int[]>,IEnumerable<keyvaluePair<string,Plate>>{


    //Store all plates as a sorted list
    //String is use for storing groups
    //i.e. 0,1,2 ... fn
    //i.e. 0;0,0;1,0;2,1;3,1;4,1;5 ... gn_fn
    private SortedList<string,Plate> sortedplates;



    public Plates() {
        sortedplates = new SortedList<string,Plate>();
    }

    #region IEnumerable Implementation
    public void Add(Plate item) => sortedplates.Add(item.fID,item);
    public IEnumerator<keyvaluePair<string,Plate>> GetEnumerator() =>  sortedplates.GetEnumerator();
    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
    #endregion

    #region IComparer


    public override int Compare(int[] x,int[] y) {

        int[] a = x.Length < y.Length ? x : y;
        int[] b = x.Length < y.Length ? y : x;

        for(int i = 0; i < a.Length; i++) {
            if (a[i] != b[i])
                return a[i].Compareto(b[i]);
        }

        return 0;

    }
    #endregion

解决方法

自定义比较器:

class KeyComparer : IComparer<string>
{
    public int Compare(string x,string y)
    {
        var xs = x.Split(';');
        var ys = y.Split(';');

        int min = Math.Min(xs.Length,ys.Length);

        for (int i = 0; i < min; i++)
        {
            int cmp = xs[i].CompareTo(ys[i]);

            if (cmp != 0)
                return cmp;
        }

        return xs.Length.CompareTo(ys.Length);
    }
}

使用:

var list = new SortedList<string,double>(new KeyComparer());

list.Add("0;1",0);
list.Add("0;0;0",0);
list.Add("0;10;1;0;0",0);
list.Add("0;2",0);
list.Add("0;10",0);
list.Add("1;0",0);
list.Add("3;1;2",0);
list.Add("2;1",0);
list.Add("3;1",0);
list.Add("0;0",0);

foreach (var x in list)
    Console.WriteLine(x);