我有一个清单
我的要求
如果条件满足则不需要分组,我需要LINQ lambda查询分组到列表。
即在某种情况下我希望将其分组 否则不应该分组
我已经搜索了网络 - 我获得了有关条件分组的详细信息,但我无法了解如何在不分组的情况下包含剩余项目。
在网上发现的一些信息是用于有条件地分组 - 但是那些不符合条件的项目不包括在结果列表中。
例如
列表= [{1,""},{40,"&#34),{9""},{52," B&#34 ),{2" b"},{99,"&#34),{88," b"}]
预期结果列表将按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,""} ]
我尝试了什么
var resultantList = sigList
.GroupBy(s => s.SignalGroup)
.Select(grp => grp.ToList())
//.Where(g => !g.Any(grp => grp.SignalGroup == ""))
.ToList();
按上述预期
取消注释Where子句组仅a和b ==>所有那些空值的项目("")都不包括在内
评论Where子句分组a,b和""字符串,用于创建包含3个组的列表(a,b和"")。
答案 0 :(得分:2)
假设第一列类似于唯一的Id
:
var resultantList = sigList
.GroupBy(s => s.SignalGroup == "" ? s.Id.ToString() : s.SignalGroup)
.Select(grp => grp.ToList())
.ToList();
因此,如果SignalGroup
为空字符串,GroupBy
将获取(唯一)ID,在所有其他情况下为SignalGroup
,因此您可以获得每个ID所需的一个组的结果SignalGroup
为""
。
如果不是唯一使用Guid.NewGuid().ToString()
作为群组的关键。
答案 1 :(得分:0)
您可以解决问题this way,完全没有多余的Id
或Guid.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);
}
}
答案 2 :(得分:0)
在您的示例中,您指定您不想分组的项目具有空字符串值。
一种解决方案,您可以指定不应对哪些值进行分组:
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)'
}
}
}
}
}
为此,我使用了我发现的here in StackOverFlow辅助类的改编版。此实现隐藏了IGrouping的实际实现。它只公开了IGrouping所需的属性和函数来创建它。如果您确实需要定期创建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();
}