基于字符串属性值在List上自定义OrderBy

时间:2018-05-27 08:43:09

标签: c# .net algorithm linq

我有以下课程:

public class Document
{
    public string DocumentSection { get; set; }
    public string DocumentName { get; set; }
}

我想基于DocumentSection属性订购以下列表:

List<Document> documents = new List<Document>();
        documents.Add(new Document { DocumentSection = "Section One", DocumentName = "doc1" });
        documents.Add(new Document { DocumentSection = "Section Two", DocumentName = "doc1123" });
        documents.Add(new Document { DocumentSection = "Section Three", DocumentName = "doc113" });
        documents.Add(new Document { DocumentSection = "Section Four", DocumentName = "doc123" });
        documents.Add(new Document { DocumentSection = "Section Five", DocumentName = "doc11" });

理论上我知道我应该实现IComparer来获得它,但这就是困难的来源,我不太确定如何在一般水平上实现这一点......实现这一目标的最佳解决方案是什么?订购?

2 个答案:

答案 0 :(得分:1)

试试这个:

var orderedList = documents.OrderBy(r => GetOrder(r.DocumentSection));

并且GetOrder()方法是:

Public Static int GetOrder(string _arg)
{
    switch (_arg)
    {
        case 'Section One':
            return 1;
        case 'Section Two':
            return 2;
        case 'Section Three':
            return 3;
            .
            .
            .
        default:
            return int.MaxValue;
    }
}

答案 1 :(得分:0)

最简单的方法是使用Linq:

List<Order> SortedList = objListOrder.OrderBy(o=>o.Order).ToList();

示例:

List<Document> SortedList = documents.OrderBy(o=>o.DocumentName).ToList();

长答案 您需要自定义上面的订单方法,但您不需要在此代码中键入所有数字

使用wordify方法,您可以将 数字转换为字

使用normalize_number方法我们将result wordfirst word标准化,以便我们可以使用第一个单词检查结果词

我们有一个循环,我们不想总是创建单词,所以我们可以使用Dictionary并检查数字,我们在get_wordify方法中执行此操作。

现在使用SetOrder我们可以找到正确的订单

所以只需使用此代码:

    private int current_order = 0;
    private int SetOrder(string _arg)
    {

        string number = _arg.ToLower()
            .Replace("section", "")
            .TrimStart(' ')
            .TrimEnd(' ');
        number = normalize_number(number);

        for (int i = 0;
            //you can limit loop here (i<99999) or not !
            ; i++)
        {
            string wordify_number = get_wordify(i);

            if (wordify_number == number)
            {
                //if all number is available return i+1
                //return i + 1;

                //otherwise
                current_order++;
                return current_order;
            }

        }

    }
    private string normalize_number(string number)
    {
        number = number.Replace("-", " ")
                        .Replace("_", " ")
                        .Replace(",", " ");

        //also you can replace "and" if you want 

        //.Replace("  ", " "); 
        //regex is better for find and replace multi space

        RegexOptions options = RegexOptions.None;
        Regex regex = new Regex("[ ]{2,}", options);
        number = regex.Replace(number, " ");


        return number;
    }

    Dictionary<int, string> Numbers_dic = new Dictionary<int, string>();
    private string get_wordify(int i)
    {
        string wordify_number = "";
        if (Numbers_dic.ContainsKey(i))
        {
            wordify_number = Numbers_dic[i];
        }
        else {
            wordify_number = wordify(i);
            wordify_number = normalize_number(wordify_number);

            Numbers_dic.Add(i, wordify_number);
        }

        return wordify_number;
    }
    private string wordify(decimal number)
    {
        if (number == 0) return "zero";
        var units = " one two three four five six seven eight nine".Split();
        var teens = " eleven twelve thir# four# fif# six# seven# eigh# nine#".Replace("#", "teen").Split();
        var tens = " ten twenty thirty forty fifty sixty seventy eighty ninety".Split();
        var thou = " thousand m# b# tr# quadr# quint# sext# sept# oct#".Replace("#", "illion").Split();
        var minus_str = (number < 0) ? "minus " : "";
        var res_number = "";
        var p = 0;
        number = Math.Abs(number);
        while (number > 0)
        {
            int b = (int)(number % 1000);
            if (b > 0)
            {
                var h = (b / 100);
                var t = (b - h * 100) / 10;
                var u = (b - h * 100 - t * 10);

                var str = ((h > 0) ? units[h] + " hundred" + ((t > 0 | u > 0) ? " and " : "") : "")
                      + ((t > 0) ? (t == 1 && u > 0) ? teens[u] : tens[t] + ((u > 0) ? "-" : "") : "")
                      + ((t != 1) ? units[u] : "");
                str = (((number > 1000) && (h == 0) && (p == 0)) ? " and " : (number > 1000) ? ", " : "") + str;

                res_number = str + " " + thou[p] + res_number;
            }

            number = number / 1000;

            if (number < 1)
            {
                break;
            }

            p++;
        }
        return minus_str + res_number;
    }

用法:

private void Do_order()
{
    var orderedList = documents.OrderBy(r => SetOrder(r.DocumentSection));
}