C # Упорядочить по элементу списка с группой - PullRequest
0 голосов
/ 28 октября 2019

У меня есть список, содержащий несколько BW объектов с 2 свойствами , равными shape и quantity.

В зависимости от значения preShape и значения preQuantity, я буду сортировать по каждому элементу в List<BW> с preShape и preQuantity. shape имеет приоритет сначала , затем quantity имеет второй приоритет. Я отсортировал List<BW> по GroupBy, затем отсортировал по shape и quantity зависит от preShape и preQuantity. Результат отлично выглядит так:

  • Значение «предварительной формы»: MN22
  • Значение «предварительной величины»: 20

| shape | quantity|
--------|----------
| MN22  | 20      |
| MN22  | 14      |
| MN11  | 20      |
| MN11  | 10      |
| ANT   | 20      |
| ANT   | 18      |
| ANT   | 16      |
| ANT   | 10      |

Но мне бы хотелось, чтобы List<BW> был таким:

| shape | quantity|
--------|----------
| MN22 | 20       |
| MN22 | 14       |
| MN11 | 10       |
| MN11 | 20       |
| ANT  | 20       |
| ANT  | 10       |
| ANT  | 16       |
| ANT  | 18       |

Я пытался использовать цикл for и функцию swap для сортировки, но результат некак то, что я ищу.

Я хотел бы отсортировать по списку с результатом, подобным 2-й таблице.

Мне нужно сгруппировать shape , чтобы объединить их в группу, и я буду сравнивать форма каждого элемента в Списке с предварительной формой , если они совпадают, я отсортирую Список с предварительной формой , затем количество будет вторым условием. Но за количеством последнего товара в группе A должно следовать то же самое количество первого товара в группе B. Если они не совпадают, то количество первого элемента в группе B будет отсортирован ASC.

Я прилагаю свой код здесь для более подробного описания мой код dottnetfiddle

public static void Main()
{
    List<BW> lst = new List<BW>(){
        new BW(){ shape = "MN11", quantity = 20},
        new BW(){ shape = "MN11", quantity = 10},
        new BW(){ shape = "MN22", quantity = 14},
        new BW(){ shape = "MN22", quantity = 20},
        new BW(){ shape = "ANT", quantity = 16},
        new BW(){ shape = "ANT", quantity = 18},
        new BW(){ shape = "ANT", quantity = 20},
        new BW(){ shape = "ANT", quantity = 10}

    };
    string preShape = "MN22";
    int preQuantity = 20;

    var tempList = lst.GroupBy(c=>c.shape).Select(g=> new {shapeGroup = g.Key, BW = g.OrderBy(c=> c.shape.Equals(preShape)).ThenByDescending(c=>c.quantity)}).OrderByDescending(g=>g.shapeGroup.Equals(preShape));
    //var tempList = lst.GroupBy(c=>c.shape).Select(g=> new {shapeGroup = g.Key, BW = g.OrderByDescending(c => c.shape.Equals(preShape))}).OrderBy(g=>g.BW.First().quantity == preQuantity);;

    foreach (var shape in tempList)
    {
        var lastGroupBW_Item = shape.BW.LastOrDefault();
        //Console.WriteLine("{0}", shape.shape);
        foreach (var bw in shape.BW)
        {
            if(shape.BW.ToList().IndexOf(bw) > 0 )
            {
                shape.BW.OrderBy(c=>c.quantity == lastGroupBW_Item.quantity).ThenBy(c=>c.quantity);
            }
            Console.WriteLine("{0}|{1}", bw.shape,bw.quantity);
        }
    }

}

Последний результат я быхотел бы иметь, как вторая таблица, которую я описал выше. Заранее спасибо!

Ответы [ 5 ]

7 голосов
/ 28 октября 2019

Таким образом, элементы с shape == preShape должны быть на верху , а также quantity == preQuantity;для этого вы можете отсортировать по bool (обратите внимание, что false < true):

 List<BW> lst = ...

 var result = lst
   .OrderByDescending(item => item.shape != preShape)       // preShape on the top  
   .ThenByDescending(item => item.shape)                    // in case of tie by shape
   .ThenByDescending(item => item.quantity != preQuantity)  // preQuantity on the top
   .ThenBy(item => item.quantity);                          // in case of tie by quantity

Демо: (я использовал Tuple для эмуляции BW)

  List<(string shape, int quantity)> lst = new List<(string shape, int quantity)>(){
    ( shape :"MN11", quantity : 20),
    ( shape :"MN11", quantity : 10),
    ( shape :"MN22", quantity : 14),
    ( shape :"MN22", quantity : 20),
    ( shape : "ANT", quantity : 16),
    ( shape : "ANT", quantity : 18),
    ( shape : "ANT", quantity : 20),
    ( shape : "ANT", quantity : 10),
  };

  string preShape = "MN22";
  int preQuantity = 20;

  var result = lst
   .OrderByDescending(item => item.shape == preShape)       // preShape on the top  
   .ThenByDescending(item => item.shape)                    // in case of tie by shape
   .ThenByDescending(item => item.quantity == preQuantity)  // preQuantity on the top
   .ThenBy(item => item.quantity);                          // in case of tie by quantity

  Console.Write(string.Join(Environment.NewLine, result));

Итог:

(MN22, 20) // preShape is the first to come; preQuantity is on the top within MN22 shape
(MN22, 14)
(MN11, 20) // preQuantity is on the top within the MIN11 shape
(MN11, 10)
(ANT, 20)  // preQuantity is on the top within the ANT shape
(ANT, 10)
(ANT, 16)
(ANT, 18)
2 голосов
/ 28 октября 2019

Я думаю, что это соответствует спецификации.

// Order by shape first; the everybody gets it part
var shapeSorted = lst
    .OrderBy(bw => bw.shape != preShape)
    .ThenByDescending(bw => bw.shape);

// Order gropus by ascending, but if equal to last item in the previous group then first
var currentSpecialQ = preQuantity;
var r = new List<BW>();
foreach(var group in shapeSorted.GroupBy(bw => bw.shape) ) {
  r.AddRange(group.OrderBy(bw => bw.quantity != currentSpecialQ).ThenBy(bw => bw.quantity));
  currentSpecialQ = r.Last().quantity;
}

Тест

Выход

MN22, 20
MN22, 14
MN11, 10
MN11, 20
ANT, 20
ANT, 10
ANT, 16
ANT, 18

Код

public class BW
{
    public string shape { get; set; }
    public int quantity { get; set; }
}
class Program
{
    public static void Main(string[] args)
    {
        List<BW> lst = new List<BW>(){
            new BW(){ shape = "MN11", quantity = 20},
            new BW(){ shape = "MN11", quantity = 10},
            new BW(){ shape = "MN22", quantity = 14},
            new BW(){ shape = "MN22", quantity = 20},
            new BW(){ shape = "ANT", quantity = 16},
            new BW(){ shape = "ANT", quantity = 18},
            new BW(){ shape = "ANT", quantity = 20},
            new BW(){ shape = "ANT", quantity = 10}

        };

        string preShape = "MN22";
        int preQuantity = 20;

        // Order by shape first; the everybody gets it part
        var shapeSorted = lst
            .OrderBy(bw => bw.shape != preShape)
            .ThenByDescending(bw => bw.shape);

        // Order gropus by ascending, but if equal to last item in the previous group then first
        var currentSpecialQ = preQuantity;
        var r = new List<BW>();
        foreach(var group in shapeSorted.GroupBy(bw => bw.shape) ) {
          r.AddRange(group.OrderBy(bw => bw.quantity != currentSpecialQ).ThenBy(bw => bw.quantity));
          currentSpecialQ = r.Last().quantity;
        }

        foreach(var bw in r ) Console.WriteLine($"{bw.shape}, {bw.quantity}");

    }
}
1 голос
/ 28 октября 2019

Используйте linq для заказа по форме, затем по количеству

var tempList = lst.OrderByDescending(x => x.shape).ThenByDescending(q => q.quantity).ToList();
foreach (var b in tempList)
{
  Console.WriteLine("{0}|{1}", b.shape,b.quantity);
}

рабочий пример здесь

0 голосов
/ 28 октября 2019

@ Решение Tymtam - правильный ответ на мой пост. Спасибо всем за помощь, я узнал еще больше о том, как использовать лямбду для сортировки по списку.

0 голосов
/ 28 октября 2019
string preShape = "MN22";
int preQuantity = 20;

Он хочет первое значение группы MN22 == preQuantity первое значение группы MN11, ближайшее к последнему из группы MN22, и первое значение группы ANT, ближайшее к последнему из группы MN11

Пример:

| MN22 | 14       |
| MN22 | 20       |
| MN11 | 10       |
| MN11 | 20       |
| ANT  | 10       |
| ANT  | 16       |
| ANT  | 18       |
| ANT  | 20       |

==>

| MN22 | 20       |
| MN22 | 14       |
| MN11 | 10       |
| MN11 | 20       |
| ANT  | 20       |
| ANT  | 18       |
| ANT  | 16       |
| ANT  | 10       |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...