admin管理员组文章数量:1384812
I take data from a datasource and group it for display. I after that, I wish to allow ad hoc filtering of the rows.
Does Linq allow me to do this without having to re-do the grouping a second time and without having to create my own implementation of IGrouping
?
The query I'd like to write is something like this:
/* for instance
var source = new string[]{ "Aa", "Ab", "B", "Bb", "C" };
Func<string,bool> filter= s => Regex.IsMatch(s, "B");
var allGroups= source.GroupBy(s => s[0]);
*/
var filteredGroups= allGroups
.Select(g=> (g.Key, g.Where(filter)))
// Cast to an IGrouping here
.Where(g => g.Count() > 0);
But the ValueTuple
created in the Select isn't an IGrouping
so that's not quite what I want.
The way I can see that doesn't involved re-grouping is to create my own implementation of IGrouping
. (Arguably this is sensible: the class would assume, not guarantee, that the grouping is consistent.)
I take data from a datasource and group it for display. I after that, I wish to allow ad hoc filtering of the rows.
Does Linq allow me to do this without having to re-do the grouping a second time and without having to create my own implementation of IGrouping
?
The query I'd like to write is something like this:
/* for instance
var source = new string[]{ "Aa", "Ab", "B", "Bb", "C" };
Func<string,bool> filter= s => Regex.IsMatch(s, "B");
var allGroups= source.GroupBy(s => s[0]);
*/
var filteredGroups= allGroups
.Select(g=> (g.Key, g.Where(filter)))
// Cast to an IGrouping here
.Where(g => g.Count() > 0);
But the ValueTuple
created in the Select isn't an IGrouping
so that's not quite what I want.
The way I can see that doesn't involved re-grouping is to create my own implementation of IGrouping
. (Arguably this is sensible: the class would assume, not guarantee, that the grouping is consistent.)
1 Answer
Reset to default 1Well, you can write very simple implementation of IGrouping
:
public class Grouping<TKey, TElement> : IGrouping<TKey, TElement>
{
private readonly IEnumerable<TElement> _elements;
public Grouping(TKey key, IEnumerable<TElement> elements)
{
Key = key;
_elements = elements;
}
public TKey Key { get; }
public IEnumerator<TElement> GetEnumerator() => _elements.GetEnumerator();
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
throw new NotImplementedException();
}
}
And then you can define some global variable (private field), to hold grouped result:
var testList = new[]
{
(Id: 1, Name: "foo"),
(Id: 1, Name: "bar"),
(Id: 2, Name: "foo"),
(Id: 2, Name: "bar")
};
var grouped = testList.GroupBy(x => x.Id).ToArray();
And implement method that would accept just the fiter, allowing you to filter groups, without requiring reqgrouping the result:
static IEnumerable<IGrouping<TKey, TElement>> Filter<TKey, TElement>(
IGrouping<TKey, TElement>[] grouped,
Func<TElement, bool> filter)
{
return grouped
.Select(g => new Grouping<TKey, TElement>(g.Key, g.Where(filter)))
.Where(g => g.Any()); // Remove empty groups
}
Putting it all together, here's sample console app:
var testList = new[]
{
(Id: 1, Name: "foo"),
(Id: 1, Name: "bar"),
(Id: 2, Name: "foo"),
(Id: 2, Name: "bar")
};
var grouped = testList.GroupBy(x => x.Id).ToArray();
var foos = Filter(grouped, item => item.Name == "foo");
var bars = Filter(grouped, item => item.Name == "bar");
本文标签: cFilter the detail rows of an already grouped list without redoing the groupingStack Overflow
版权声明:本文标题:c# - Filter the detail rows of an already grouped list without re-doing the grouping - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744511556a2609915.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论