使用另一个集合进行排序

本文关键字:排序 集合 另一个 | 更新日期: 2023-09-27 18:15:50

我有一个独特的排序问题,在这个问题中,我有一个以"顺序"给我的对象数组,但我不知道顺序,或者根据对象的任何特定属性进行排序。

对象如下

public class Case
{
    public virtual int Id { get; set; }
    public virtual string PalletId { get; set; }
}

我需要做的是获取我给定的Cases s数组并创建这些对象的新列表,该列表按原始集合PalletId字段的相对顺序排序,然后按它的id字段排序。在这个字段中,它不是绝对顺序,因为它是相对于集合的原始顺序的。

例如:

原来集合

Id ---------- PalletId
1 ----------- 5
2 ----------- 6
3 ----------- 4
4 ----------- 5
5 ----------- 6
6 ----------- 4

分类收集

Id ---------- PalletId
1 ----------- 5
4 ----------- 5
2 ----------- 6
5 ----------- 6
3 ----------- 4
6 ----------- 4

上面的排序集合表示我需要如何对这些进行排序。请注意,排序集合中的托盘不是按升序或降序排列的,而是按照您在原始集合中看到的顺序(5,6,4)进行排序。在每个托盘id中,我必须以相同的顺序对id字段进行排序。因此,这是我在原始集合中看到特定托盘Id的Id字段的顺序。

使用另一个集合进行排序

澄清之后,一个简单的GroupBy + SelectMany似乎就能解决问题了:

var sortedCases = originalCases
    .GroupBy(c => c.PalletId)
    .SelectMany(g => g.OrderBy(c => c.Id)) ;

As GroupBy()根据这个SO答案保留键的初始顺序。

Use order

var orderedCases = Cases.OrderByDescending(c => c.PalletId).ThenBy(c => c.Id);

这给出了正确的答案,但是看起来有点繁琐!

在Id值降序的情况下,它给出了与Henk不同的答案。我想这可能是OP想要的,但我不完全确定。

using System;
using System.Collections.Generic;
namespace Demo
{
    class Item
    {
        public int Id;
        public int PalletId;
        public override string ToString()
        {
            return string.Format("{0}, {1}", Id, PalletId);
        }
    }
    class Program
    {
        void run()
        {
            var items = new []
            {
                new Item { Id = 1, PalletId = 5},
                new Item { Id = 2, PalletId = 6},
                new Item { Id = 3, PalletId = 4},
                new Item { Id = 4, PalletId = 5},
                new Item { Id = 5, PalletId = 6},
                new Item { Id = 6, PalletId = 4}
            };
            sortItems(items);
            items.Print();
        }
        void sortItems(Item[] items)
        {
            for (int i = 0, j = 1; i < items.Length && j < items.Length; i = j, j = i + 1)
            {
                while ((j < items.Length) && (items[i].PalletId == items[j].PalletId))
                    ++j;
                for (int k = j+1; k < items.Length; ++k)
                {
                    if (items[k].PalletId == items[i].PalletId)
                    {
                        move(items, j, k);
                        break;
                    }
                }
            }
        }
        void move(Item[] items, int to, int from)
        {
            var temp = items[from];
            for (int i = from; i > to; --i)
                items[i] = items[i-1];
            items[to] = temp;
        }
        static void Main()
        {
            new Program().run();
        }
    }
    static class DemoUtil
    {
        public static void Print(this object self)
        {
            Console.WriteLine(self);
        }
        public static void Print(this string self)
        {
            Console.WriteLine(self);
        }
        public static void Print<T>(this IEnumerable<T> self)
        {
            foreach (var item in self) Console.WriteLine(item);
        }
    }
}