对复杂的数组进行排序

时间:2017-07-18 13:41:09

标签: c# arrays algorithm sorting

我有700个小组。我需要按照特定的规则对数组进行排序:

  1. 我们需要按公司名称排序
  2. 层次结构取决于groups.Name
  3. 中的点数
  4. 有很多具有相同公司名称的记录,但是从特定公司展示的第一个记录必须包含".All"。在此记录之后,我们需要将所有其他名称排在"1."
  5. 之前
  6. 直接向公司申请职位的具体情况
  7. 示例:

    groups[0].CompanyName = "Acompany"
    groups[1].CompanyName = "Acompany"
    groups[2].CompanyName = "Acompany"
    groups[3].CompanyName = "Acompany"
    groups[4].CompanyName = "Acompany"
    groups[5].CompanyName = "Bcompany"
    groups[6].CompanyName = "Bcompany"
    groups[7].CompanyName = "Bcompany"
    
    groups[0].Name = "Acompany.All" //(root)
    groups[1].Name = "D.Acompany.example" //this is the specific case (leaf) 
    groups[2].Name = "Acompany.ABC"//(group)
    groups[3].Name = "D.Acompany.ABC.PrimaryTeacher" //(leaf)
    groups[4].Name = "Acompany.ABC.Something"//(group)
    groups[5].Name = "Bcompany.All" //(root)
    groups[6].Name = "Bcompany.Sites"//(group)
    groups[7].Name = "Bcompany.Sites.example" //(leaf)
    

    该示例显示了排序后数组的外观。它真的很复杂,我希望我能解释它。

    目前我已经实现了:

    enter image description here

    有两个问题:

    1.D.A.1stFloor.Cleaner必须在A.1stFloor下

    2.D.B.Society.Worker必须在B.Society

    之下

    我现在的代码:

    Array.Sort(groups, (a, b) =>
            {              
                if (a.CompanyName != b.CompanyName)
                {
                    return a.CompanyName.CompareTo(b.CompanyName);
                }
    
                if (a.Name.Contains(".All"))
                {                  
                    return -1;
                }
    
                if (b.Name.Contains(".All"))
                    return 1; 
    
                if (a.Name.StartsWith("D.") && a.Name.Count(x => x == '.') == 2)
                    return -1;
                if (b.Name.StartsWith("D.") && b.Name.Count(x => x == '.') == 2)
                    return 1;
    
                if (a.Name.Count(x => x == '.') == 1)
                    return -1;
                if (b.Name.Count(x => x == '.') == 1)
                    return 1;
    
                if (a.Name.StartsWith("D") && a.Name.Count(x => x == '.') == 3) //needs to be moved I guess
                    return -1;
                if (b.Name.StartsWith("D") && b.Name.Count(x => x == '.') == 3)//needs to be moved I guess
                    return 1;
    return a.Name.CompareTo(b.Name);
            });
    

3 个答案:

答案 0 :(得分:1)

根据您的规则和字符串处理函数,您将每个公司构建为树,如下图所示,ACompany:

enter image description here

然后您只需使用Depth-First Tree traversal算法来获取订单。

答案 1 :(得分:0)

我无法想象您的排序规则有多复杂,抱歉。但是,我建议您利用现有的排序功能。

将每个群体构建为一个对象,我相信你已经做到了:

public class Company
{
    public string CompanyName { get; set; }
    public string Name { get; set; }
}

因此,您的小组只是一个阵列或公司列表。

var group = new List<Company>();

然后,在定义的比较器中实现排序规则:

public class CoordinatesBasedComparer : IComparer<Company>
{
    public int Compare(Company a, Company b)
    {
        //your sorting rules implemented here   
    }
}

最后,您只需致电:

    var comparer = new CoordinatesBasedComparer();
    group.Sort(comparer);

希望这有帮助。

答案 2 :(得分:0)

您的规则并不完全清楚,但这是使用比较器进行排序的示例:

Array.Sort(groups, (a, b) =>
{
    // highest priority rule
    if (a.CompanyName != b.CompanyName)
    {
        return a.CompanyName.CompareTo(b.CompanyName); // or a custom comparison
    }

    // more rules ordered by priority
    if (a.Name == a.CompanyName + ".All")
        return -1; // => "a" comes first

    if (b.Name == b.CompanyName + ".All")
        return 1; // => "b" comes first

    // more rules...

    // default rule
    return a.Name.CompareTo(b.Name);
});