简体   繁体   中英

Sorting a multi object list based on a template in c#

I have a list like:

| Name | number | order |  
|------|--------|-------|
| rt   | 7432   | down  |
| ht   | 2000   |  up   |
| hr   | 2730   |  up   |   
| cc   | 1000   | down  |
| af   | 1430   | down  |  
| ge   | 3000   |  up   |
| bb   | 4800   | down  |
| ke   | 1200   |  up   |
| wd   | 1100   |  up   |

what i need to do is to sort this list like:

| name | number | order |
|------|--------|-------|
| ge   |  3000  |  up   |
| hr   |  2730  |  up   |
| ht   |  2000  |  up   |
| ke   |  1200  |  up   |
| cc   |  1000  | down  |
| wd   |  1100  |  up   |
| af   |  1430  | down  |
| bb   |  4800  | down  |
| rt   |  7432  | down  |
  • Note
    1. the list is divided into two groups "up" and "down"
    2. the "number" column is ordered based on : high, middle, low/low, middle, high
    3. Regardless of the "up" and "down" grouping, the lowest number should be in the middle, when the number of rows are odd and one of the middle rows when the rows are even.

are there any efficient way of creating this new list without having to check every row and placing it into the new list !!??

your input is greatly appreciated

Overall, having to place the "middle" element is the most problematic here. Otherwise it would be easy to implement IComparer or simply use linq for it.

Still, you don't have to check every value manually. I don't think the below linq code is optimal, but it's fairly simple. I used MinBy implementation provided here to get the minimal object and Tuple to not implement classes:

        List<Tuple<string,int,string>> list = new List<Tuple<string,int,string>>();
        list.Add(Tuple.Create<string, int, string>("a",100,"up"));
        list.Add(Tuple.Create<string, int, string>("b",99,"up"));
        list.Add(Tuple.Create<string, int, string>("c",120,"up"));
        list.Add(Tuple.Create<string, int, string>("d",200,"up"));

        list.Add(Tuple.Create<string, int, string>("e",112,"down"));
        list.Add(Tuple.Create<string, int, string>("f",10,"down"));
        list.Add(Tuple.Create<string, int, string>("g",110,"down"));

        var temp=list.ToLookup(x => x.Item3);

        var up = temp["up"].OrderByDescending(a => a.Item2);
        Tuple<string, int, string> lowestUp = up.MinBy(a => a.Item2);

        var down=temp["down"].OrderBy(a => a.Item2);
        Tuple<string, int, string> lowestDown = down.MinBy(a => a.Item2);

        if (lowestDown.Item2 < lowestUp.Item2)
        {
            var result = up.Union(down.Except(new Tuple<string, int, string>[] { lowestDown })).ToList();
            result.Insert(result.Count / 2, lowestDown);
        }
        else
        {
            var result = up.Except(new Tuple<string, int, string>[] { lowestUp }).Union(down).ToList();
            result.Insert(result.Count / 2, lowestUp);
        }

EDIT: I interepreted "middle" as the element with index count/2.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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