简体   繁体   English

C#中的自定义字符串比较

[英]Custom string Comparison in C#

I want to implement a custom string IComparer in C# and apply it to a ComboBox. 我想在C#中实现自定义字符串IComparer并将其应用于ComboBox。

Actual Results 实际结果

If I set the ComboBox 's Sorted property to true , the output is : 如果我将ComboBoxSorted属性设置为true ,则输出为:

A
AA
AAA
B
BB
BBB

Wanted Results 通缉结果

The wanted behavior of the sorting algorithm is the following (financial developers will understand why :) ) : 排序算法的通缉行为如下(金融开发人员将理解为什么:)):

AAA
AA
A
BBB
BB
B

Question

Is it possible to do it ? 有可能吗? Are sorting algorithms needed here ? 这里需要排序算法吗?

PS : I don't need a complete answer with code, i just need an idea of how it might be done .. PS:我不需要完整的代码答案,我只需要了解它是如何完成的。

EDIT 编辑

This is about credit ratings. 这是关于信用评级。 I've omitted something in my question. 我在我的问题中省略了一些内容。 The ratings have to be sorted in this order : 评级必须按以下顺序排序:

XXX
XX+
XX
XX-
X+
X
X-

with X in ('A','B','C') and 'A' > 'B' > 'C' X in ('A','B','C')'A' > 'B' > 'C'

Here's a mostly implemented version: 这是一个主要实现的版本:

public class MyComparer : IComparer<string>
{
    public int Compare(string x, string y)
    {
        //todo null checks on input

        var pairs = x.Zip(y, (a, b) => new { x = a, y = b });

        foreach (var pair in pairs)
        {
            int value = pair.x.CompareTo(pair.y);
            if (value != 0)
                return value;
        }


        //if we got here then either they are the same,
        //or one starts with the other
        return y.Length.CompareTo(x.Length); //note x and y are reversed here
    }
}

So this uses Zip to get the pairs of chars from each corresponding string until one ends, returning the appropriate value if they aren't equal. 因此,这使用Zip从每个对应的字符串中获取字符对,直到结束,如果它们不相等则返回适当的值。 If it makes it past that then one string start with the other. 如果它超过了那个,那么一个字符串从另一个字符串开始。 For a traditional string comparison we'd just compare the lengths in the same order as the input parameters. 对于传统的字符串比较,我们只是按照与输入参数相同的顺序比较长度。 Since we're essentially reversing the order based on length, note that the x and y are swapped on the last line. 由于我们基本上是根据长度反转顺序,请注意xy在最后一行交换。 That reverses the comparison logic. 这颠倒了比较逻辑。

Assuming this is for credit ratings, normally this is done by having a "sort order" column on the CreditRating class that you could use to sort the list before assigning it as the data source of the drop-down. 假设这是用于信用评级,通常通过在CreditRating类上设置“排序顺序”列来完成,您可以使用该列对列表进行排序,然后将其指定为下拉列表的数据源。

But, a quick workaround (based on the limited possible values) would be to sort by the first letter ascending, then by the length of the string descending: 但是,快速解决方法(基于有限的可能值)将按升序的第一个字母排序,然后按字符串降序的长度排序:

if(left[0] != right[0])
    return left[0].CompareTo(right[0]);
else
    return right.Length - left.Length;

Another workaround if you want more control over the order is to create a list of possible values in the "right" order and then use that to sort the list: 如果您想要更多地控制订单,另一种解决方法是以“正确”顺序创建可能值的列表,然后使用它来对列表进行排序:

public class MyComparer : IComparer<string>
{
    private static readonly string[] Ratings = new [] {
        "CC","C","CCC-","CCC","CCC+",
        "B-","B","B+","BB-","BB","BB+","BBB-","BBB","BBB+",
        "A-","A","A+","AA-","AA","AA+","AAA"};
    // reverse the order so that any strings not found will be put at the end.

    public int Compare(string left, string right)
    {
       return Array.IndexOf(Ratings, right).CompareTo(Array.IndexOf(Ratings, left));
    }
}

Write the IComparer so that it takes strings but compares per character, 编写IComparer,使其占用字符串,但每个字符进行比较,

if A[0] == B[0] go to the next character.
if B[1] == null or A[1] < B[1], return A < B.
if A[1] == null or B[1] < A[1], return B < A.
if equal...continue as needed

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM