我想获得带有ObservableCollection的Linq的前N个组元素,这个例子试图获得前两个组:
数据示例:
GROUP1 item1
GROUP1 item2
GROUP1 item3
GROUP2 item1
GROUP2 item2
GROUP3 item1
GROUP3 item2
GROUP3 item3
GROUP4 item1
GROUP4 item2
GROUP4 item3
想要的结果:
GROUP1 item1
GROUP1 item2
GROUP1 item3
GROUP2 item1
GROUP2 item2
希望有人可以帮助我。有什么想法吗?
您能提供VB.Net样本吗?
非常感谢。
答案 0 :(得分:3)
如果您的论坛总是这样排序,您可以使用GroupBy()
获取所有论坛,然后Take(2)
仅获取前两个论坛,然后使用SelectMany()
进行更改这些组回到一个单一的序列中:
data.GroupBy(x => x.Group)
.Take(2)
.SelectMany(g => g);
虽然这种方法效率低下,因为它枚举了整个集合。如果您想提高效率,可以编写自己的扩展方法来执行此操作:
public IEnumerable<T> TakeGroups<T, TGroup>(
this IEnumerable<T> source, Func<T, TGroup> groupSelector, int groupLimit)
{
int groupNumber = 0;
TGroup lastGroup = default(TGroup);
foreach (var item in source)
{
if (groupNumber == 0)
{
groupNumber = 1;
lastGroup = groupSelector(item);
}
else
{
var currentGroup = groupSelector(item);
if (!object.Equals(currentGroup, lastGroup))
{
groupNumber++;
lastGroup = currentGroup;
}
}
if (groupNumber > groupLimit)
break;
yield return item;
}
}
并像这样使用它:
data.TakeGroups(x => x.Group, 2)
答案 1 :(得分:2)
myList.GroupBy(x=>x.GroupName).Where(x=>x.Key == "Group1" || x.Key == "Group2");
Edit:
对于您没有群组名称的情况,您应该有可能的群组名称列表或类似内容,我将此群组列表命名为groupList
:
myList.Where(x=>groupList.Contains(x=>x.GroupName);
或者,如果你总是想要前两组:
myList.GroupBy(x=>x.GroupName).OrderBy(x=>x.Key).Take(2).SelectMany(x=>x);
答案 2 :(得分:2)
您可以按组名称进行分组,将组数限制为N(示例中为2),然后使用SelectMany()
再次展平列表:
var query = observableList.GroupBy(x=> x.GroupName)
.Take(2)
.SelectMany(x => x);
答案 3 :(得分:0)
您想要使用Take(5),或者如果您想限制群组,那么您只想使用Where method
.Where(x=>(x.Group == "Group1" || x.Group == "Group2"));
//You COULD use Contains depending on your type
答案 4 :(得分:0)
(假设集合已按您的意愿排序):
Dim query = data.GroupBy(Function(x) x.Group).Take(2).SelectMany(Function(g) g)
请参阅@ svick关于这种方法效率低下的详细解释......