0

I have a big array of 700 groups. I need to sort the array by specific rules:

  1. We need to sort by company name
  2. Hierarchy depends on the number of points in the groups.Name
  3. There are a lot of records with same company name, but the first one to show from specific company must contain ".All". After this record, we need to put all others with the same name ordered by "1."
  4. Specific case when there is a position directly applied to the company

Example:

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)

The example shows how the array should look like after sort. It's really complicated, I hope I have managed to explain it.

For now I have achieved:

enter image description here

There are 2 problems :

1.D.A.1stFloor.Cleaner must be under A.1stFloor

2.D.B.Society.Worker must be under B.Society

My code for now :

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
  • The convention used for D.* is not clear. So it will be hard for anyone to tell you the right algo for sorting. Anyway, is this data dynamic, meaning is it going to change very frequently? I suppose its static data and the grouping / hierarchy is not going to change as such. In which case I will suggest that you add another column to manage the parent - child relationship. It will be a one time activity but it will help you in sorting. Commented Jul 18, 2017 at 14:59
  • D means it's a positioun under a group. It can be a position under the .All group, it can be a group under a other group. Let's take from the example 1st.floor group or 2ndfloor group Commented Jul 19, 2017 at 6:34
  • Sounds contradictory. At once you are saying D means it's a positioun under a group and then you are also saying it can be a group under a other group. That's Confusing. Have you considered using separate column to manage hierarchy? Commented Jul 19, 2017 at 6:55

3 Answers 3

1

You construct each company as a tree, like the image below for ACompany, base on your rules and string processing functions:

enter image description here

Then you just need to use a Depth-First Tree traversal algorithm to get the order.

Sign up to request clarification or add additional context in comments.

2 Comments

You can write up your code, if you have anything need to support, I am willing to help
I have added the code written by me till now and image of the result. Now the only thing left is to input D. in the correct group. I have managed to do that only for the .All group
0

I cannot imagine how complicated your sorting rules is, sorry. But, I would like to suggest you to take advantage of existing sorting function.

Construct each group as an object, I believe that you've done that:

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

So, your group is just an array or list of Companies.

var group = new List<Company>();

Then, you implement your sorting rules in your defined comparer:

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

Finally, you just call:

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

Hope this helps.

9 Comments

well, with simple words. It looks like tree. We have lot of groups. Let's say we have 2 companies "A" and "B". So first in the array should be the groups with companyName "A", then the first one which is the root has name "A.All" . Under "A.All" u can have a leaf D.A.Something this should be the 2nd item in the array. After that if there is a group under the rood, it should be the 3rd element , let's say it's A.2ndFloor, here u can have again D.2nd.Floor.position or another group which will be under 2nd floor, so we will caled it 3rdFloor and so on. After A, we start with Bcompany
I see you are defining comparer, but my problem is not that, it's finding the correct logic/algorithm.
So groups here is your desired output? Can you just draw an image for easier understanding? And how are you constructing your input - tree?
I have added a picture of how it should look when I pass the array in order to generate an excel file with the ordered array
Your BCompany is quite clear, but it's better if you can explain more on ACompany and what do you mean by "2. Hierarchy depends on the number of points in the groups.Name"?
|
0

Your rules are not entirely clear, but here's an example of sorting with a comparator:

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);
});

1 Comment

I have added a picture of how it should look when I pass the array in order to generate an excel file with the ordered array. I hope it is more understandable

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.