使用linq可根据元素属性将列表重新排序为重复组

本文关键字:新排序 排序 列表 linq 元素 属性 使用 | 更新日期: 2023-09-27 18:03:55

我想知道我正在尝试做的某种排序和项目收集是否可能使用LINQ。

我有一个属于某个订阅的人的列表。

这样的类:

public class Person
{
   public string name {get; set;}
   public int subscriptionId {get; set;}
}

假设我有一个数据列表,如:

Subscription ID | Name
--------
1 - bob
1 - River
5 - Phil
2 - Jayne
2 - Malcolm
5 - Doug
2 - Kaylee
2 - Joe
1 - Dan
1 - Greg
5 - Zoe
2 - Carl
5 - Kerney

,我希望列表的结尾是:

1 - bob
1 - River
2 - Jayne
2 - Malcolm
5 - Phil
5 - Doug
//  Note that the subscriber id repeats in the same pattern.
1 - Dan
1 - Greg
2 - Kaylee
2 - Joe
5 - Zoe
5 - Kerney
// No more 1 or 3 subscibers so we have only Carl
2 - Carl

在本例中请注意,在第二个列表中,我们从第一个订阅中获取2个人,然后从第二个订阅中获取2个人,以此类推。然后,在遍历所有订阅后,我们从第一个订阅开始,获取下一个订阅者,重复该过程,直到枚举了所有订阅者。

编辑:

基本上,我问的是,在linq中,是否有可能取一个项目列表,并以重复的模式对它们进行排序。因此,在上面的示例中,您将首先按subscriptionId排序,然后将取2移到下一个最低的subscriptionId并再次取2,并保持该顺序,直到需要重复该过程。所以在上面的例子中,它是:1,1,2,2,5,5,1,1,2,2,5,5,2

编辑2:

我写了一个简短的代码片段,我相信它完成了我想做的事情。询问linq查询是否存在的原因是,是否有可能将此功能放入一个列表中,然后循环遍历该列表。

            List<int> subscriptionIds = people.Select(s => s.subscriptionId).Distinct().ToList();
            List<List<Person>> jaggedPersonArray = subscriptionIds.Select(sId => people.Where(s => s.subscriptionId == sId).ToList()).ToList();
            int subscriptionsHit = 0;
            int jaggedPersonArrayIndex = 0;
            int personsIndex = 0;
            while (people.Count - subscriptionsHit > 0)
            {
                List<Person> doStuffList = jaggedPersonArray[jaggedPersonArrayIndex].Skip(personsIndex).Take(2).ToList();
                subscriptionsHit += doStuffList.Count;
                //do stuff with doStuffList
                if (jaggedPersonArrayIndex >= jaggedPersonArray.Count - 1)
                {
                    jaggedPersonArrayIndex = 0;
                    personsIndex += 2;
                }
                else
                {
                    jaggedPersonArrayIndex++;
                }
            }

使用linq可根据元素属性将列表重新排序为重复组

这个LINQ表达式将生成您所要求的输出,其中每个人组中最多列出两个具有给定订阅ID的人。

List<Person> groupedPeople = people
    // Group the list by id
    .GroupBy(p => p.SubscriptionId)  
    // Expand into a collection of anonymous objects with a group key 
    // set by the position in the group
    .SelectMany(g => g.Select((p, i) => new 
        { GroupKey = i / 2, SubscriptionId = p.SubscriptionId, Person = p }))
    // Re-order the list by group key and subscription ID
    .OrderBy(x => x.GroupKey).ThenBy(x=> x.SubscriptionId)
    // Extract the original objects
    .Select(x => x.Person);

关键表达式为GroupKey = i / 2。分母的值为2表示每组中最多允许有2个条目