简体   繁体   English

C#Linq如果条件满足则分组到列表,否则不分组

[英]C# Linq to Group to a list if a Condition meets else do not group

I have a list 我有一个清单
My Requirement 我的要求

I need a LINQ lambda query to Group to a list if a Condition meets else do not group. 如果条件满足,我需要一个LINQ lambda查询将其分组到列表,否则不进行分组。

ie On a condition I want it to be grouped 即在条件下我希望将其分组
else it should not be grouped 否则不应该分组

I have searched net - I get details on grouping on condition and I couldn't get and understand on how the remaining item should be included without grouping. 我已经搜索过网络-我得到了有关按条件分组的详细信息,而我却无法理解如何在不分组的情况下将剩余的物品包括在内。

Some info found on net was for grouping Conditionally - but with that those items not meeting conditions do not include in the resultant list. 在网络上找到的一些信息用于有条件地分组-但是,那些不符合条件的项目不包括在结果列表中。

For Example 例如

List = [{1,"a"},{40,""),{9,"a"},{52,"b"),{2,"b"},{99,""),{88,"b"}] 列表= [{1,“ a”},{40,“”),{9,“ a”},{52,“ b”),{2,“ b”},{99,“”),{ 88,“ b”}]

The expected resultant list is to be grouped by a,b but "" should not be grouped 预期结果列表将按a,b分组,但不应将“”分组

ResultantList = Group[0] ==> [{1,"a"}
                             {9,"a"}],
                 Group[1] ==>[ {52,"b"),
                               {2,"b"},
                               {88,"b"}] ,
                 // all other items which is "" should be included without groups
                Group[3] [ {40,""}]  
                 Group[4][ {99,""} ] 

What I have tried 我尝试过的

var resultantList =  sigList
                    .GroupBy(s => s.SignalGroup)
                    .Select(grp => grp.ToList())
                     //.Where(g => !g.Any(grp => grp.SignalGroup == ""))
                     .ToList();

With the above as expected 符合预期

  1. Uncommenting Where clause groups only a and b==> All those items with empty value ( "" ) does not get included 取消注释Where子句仅将a和b ==>组所有不包含空值(“”)的项目

  2. Commenting Where clause groups a,b and "" string to make a list with 3 groups(a,b and ""). 注释Where子句将a,b和“”字符串分组,以形成具有3个组(a,b和“”)的列表。

Assuming that the first column is something like a unique Id : 假设第一列类似于唯一Id

var resultantList =  sigList
    .GroupBy(s => s.SignalGroup == "" ? s.Id.ToString() : s.SignalGroup)
    .Select(grp => grp.ToList())
    .ToList();

So if SignalGroup is an empty string the GroupBy takes the (unique) Id, in all other cases the SignalGroup , so you get the desired result of one group per Id if SignalGroup is "" . 因此,如果SignalGroup是一个空字符串,则GroupBy将采用(唯一)ID,在所有其他情况下,则采用SignalGroup ,因此,如果SignalGroup""则每个ID将获得一组期望的结果。

If it's not unique use Guid.NewGuid().ToString() as key for the group. 如果不是唯一的,请使用Guid.NewGuid().ToString()作为组的键。

You can solve your problem this way , without redundant Id or Guid.NewGuid() at all: 您可以通过这种方式解决您的问题, Guid.NewGuid()不需要冗余的IdGuid.NewGuid()

public class Test
{
    public string property { get; set; }
    public string name { get; set; }
}

public static void Main()
{
    var items = new List<Test>()
    {
        new Test{ property = "1", name = "1" },
        new Test{ property = "1", name = "2" },
        new Test{ property = "2", name = "3" },
        new Test{ property = "2", name = "4" },
        new Test{ property = "", name = "5" },
        new Test{ property = "", name = "6" }
    };

    var result = items
            .GroupBy(x => x.property == "")
            .SelectMany(x =>
                !x.Key ?
                    x.GroupBy(y => y.property).Select(y => y.ToList()).ToList() 
                    :
                    x.Select(y => new List<Test> { y }).ToList()
                ).ToList();

    foreach (var res in result)
    {
        Console.WriteLine("Group " + res.First().property + ":");
        foreach (var item in res)
            Console.WriteLine(item.name);
    }
}

In your example you specify that the items that you don't want to group have an empty string value. 在示例中,您指定不想分组的项目具有空字符串值。

A solution where you can specify which values should not be grouped: 一种解决方案,您可以在其中指定不应分组的值:

static class EnumerableExtensions
{
    public static IEnumerable<IGrouping<TKey, TSource>> SpecialGroupBy(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector,
        TKey dontGroupKeyValue)
    {
        // Group all items according to the keySelector,
        // return all groups, except the group with the key dontGroupKeyValue

        var groups = source.GroupBy(keySelector);
        foreach (IGrouping<TKey, TSource> group in groups)
        {
            if (group.Key != dontGroupKeyValue)
            {  // return this as a group:
               return group;
            }
            else
            {   // return every element of the group as a separate IGrouping
                foreach (TSource element in group)
                {
                   return Grouping.Create(dontGroupKeySelector, element)'
                }
             }
         }
    }
}

For this I use an adaptation of a helper class I found here in StackOverFlow . 为此,我使用在StackOverFlow中找到的帮助程序类的改编。 This implementation hides the actual implementation of the IGrouping. 此实现隐藏了IGrouping的实际实现。 It only exposes the IGrouping required properties and functions to create it. 它仅公开IGrouping所需的属性和函数来创建它。 If you do need to Create IGrouping regularly consider putting this in some base library. 如果确实需要定期创建IGrouping,请考虑将其放在某个基础库中。

public class Grouping<TKey, TElement> : IEnumerable<TElement>, IGrouping<TKey, TElement>
{
    public static IGrouping<TKey, TElement> Create(TKey key, TElement element)
    {
        return new Grouping<TKey, TElement>()
        {
            Key = key,
            Elements = new TElement[] {element},
        };
    }
    public static IGrouping<TKey, TElement> Create(TKey key,
        IEnumerable<TElement> elements)
    {
        return new Grouping<TKey, TElement>()
        {
            Key = key,
            elements = elements,
        };
    }

    private Grouping() { }

    public TKey Key { get; private set; }
    private IEnumerable<TElement> elements;

    public IEnumerator<TElement> GetEnumerator() => this.elements.GetEnumerator();
    IEnumerator IEnumerable.GetEnumerator() => this.GetEnumerator();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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