• 排序集合的一个小坑


      原来一直用SortList,SortedDictionary来作为键值对存储的排序集合来用,心中就默认是以key按ascall排序来存放的,在之前的案例中也没有出现问题,在最近一个demo中,打破了原来的自以为是的认识,因为在key中不但有大写小,还有特列符号。

      先看一下代码:

    Console.WriteLine("-----------按ASCII排序-----------");
    var chars = new char[] { 'A', '[', ']', 'a' };
    foreach (var c in chars)
    {
        Console.WriteLine($"{c}:{(int)c}");
    }
    Console.WriteLine("-----------排序集合的排序-----------");
    var list = new SortedList<string, int>();
    list.Add("a", 97);
    list.Add("A", 65);
    list.Add("[", 91);
    list.Add("]", 93);
    foreach (var item in list)
    {
        Console.WriteLine($"{item.Key}:{item.Value}");
    }

    结果如下,显然SortList的key结果不是想要的按ascall排序的。

     

     

      那怎么才能达到按ascall呢?那就自己动手做一个排序器吧,其实就是实现IComparer<string>接口中的Compare,告诉两个string的比较规则,那自然多个数据的排序就能按这种规则给出来。当然我给的按ascall的这个规则,丝毫没有优美而言,只是能表示出意思来。

    Console.WriteLine("-----------新排序集合的排序-----------");
    var newList = new SortedList<string, int>(new ASCALLComparer());
    newList.Add("a", 97);
    newList.Add("A", 65);
    newList.Add("[", 91);
    newList.Add("]", 93);
    foreach (var item in newList)
    {
        Console.WriteLine($"{item.Key}:{item.Value}");
    }
    
    public class ASCALLComparer : IComparer<string>
    {
        public int Compare(string? x, string? y)
    {
            if (x == null || y == null)
            {
                throw new Exception("x or y is null");
            }
            if (x?.Length != y?.Length)
            {
                if (x?.Length < y?.Length)
                {
                    for (var i = 0; i < x?.Length; i++)
                    {
                        if ((int)x[i] > (int)y[i])
                        {
                            return 1;
                        }
                        else if ((int)x[i] < (int)y[i])
                        {
                            return -1;
                        }
                    }
                    return -1;
                }
                else
                {
                    for (var i = 0; i < y?.Length; i++)
                    {
                        if ((int)x[i] > (int)y[i])
                        {
                            return 1;
                        }
                        else if ((int)x[i] < (int)y[i])
                        {
                            return -1;
                        }
                    }
                    return 1;
                }
            }
            else
            {
                for (var i = 0; i < x?.Length; i++)
                {
                    if ((int)x[i] > (int)y[i])
                    {
                        return 1;
                    }
                    else if ((int)x[i] < (int)y[i])
                    {
                        return -1;
                    }
                }
                return 0;
            }
        }
    }

      结果为:

     

     

      那原来的排序规则是什么呢?我枚举了一下ascall范围内部分可见字符,下面是正序的排序方式:

    序号 符号 ascall值

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    22

    23

    24

    25

    26

    27

    28

    29

    30

    31

    32

    33

    34

    35

    36

    37

    38

    39

    40

    41

    42

    43

    44

    45

    46

    47

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    58

    59

    60

    61

    62

    63

    64

    65

    66

    67

    68

    69

    70

    71

    72

    73

    74

    75

    76

    77

    78

    79

    80

    81

    82

    83

    84

    85

    86

    87

    88

    89

    90

    91

    92

    93

    94

    95

    96

    97

    98

    99

    100

    101

    _

    -

    ,

    ;

    :

    !

    ?

    .

    '

    "

    (

    )

    [

    ]

    {

    }

    @

    *

    /

    \

    &

    #

    %

    `

    ^

    +

    <

    =

    >

    |

    ~

    $

    0

    1

    2

    3

    4

    5

    6

    7

    8

    9

    a

    A

    b

    B

    c

    C

    d

    D

    e

    E

    f

    F

    g

    G

    h

    H

    i

    I

    j

    J

    k

    K

    l

    L

    m

    M

    n

    N

    o

    O

    p

    P

    q

    Q

    r

    R

    s

    S

    t

    T

    u

    U

    v

    V

    w

    W

    x

    X

    y

    Y

    z

    Z

    95

    45

    44

    59

    58

    33

    63

    46

    39

    34

    40

    41

    91

    93

    123

    125

    64

    42

    47

    92

    38

    35

    37

    96

    94

    43

    60

    61

    62

    124

    126

    36

    48

    49

    50

    51

    52

    53

    54

    55

    56

    57

    97

    65

    98

    66

    99

    67

    100

    68

    101

    69

    102

    70

    103

    71

    104

    72

    105

    73

    106

    74

    107

    75

    108

    76

    109

    77

    110

    78

    111

    79

    112

    80

    113

    81

    114

    82

    115

    83

    116

    84

    117

    85

    118

    86

    119

    87

    120

    88

    121

    89

    122

    90

     

      想要更快更方便的了解相关知识,可以关注微信公众号 
     

     

     

  • 相关阅读:
    【设计】B端图表设计
    用 SpringBoot,亲自打造一个在线题库系统
    玩点创意编程,发现另一个世界
    Spring Security 基本介绍,初窥路径
    一个课程,11个项目!爬虫初体验,快来!
    黑三兵后现缓涨很危险 出现急涨有转机
    JavaScript对象之get/set方法
    ES6-ES11新特性
    js常见设计模式
    再谈promise
  • 原文地址:https://www.cnblogs.com/ljknlb/p/16023623.html
Copyright © 2020-2023  润新知