C# LINQ和set属性中的GroupBy
我有这样的课:C# LINQ和set属性中的GroupBy,c#,linq,group-by,C#,Linq,Group By,我有这样的课: public class Foo { public string Regn{get;set;} public string DocName{get;set;} ... } 在我的应用程序中,该类与IEnumerable一起使用: IEnumerable<Foo> items; [更新] 输入样本: Regn DocName 1 1 1 2 1 2 2 5 2 5 2 6 输出: Regn DocName 1
public class Foo
{
public string Regn{get;set;}
public string DocName{get;set;}
...
}
在我的应用程序中,该类与IEnumerable一起使用:
IEnumerable<Foo> items;
[更新]
输入样本:
Regn DocName
1 1
1 2
1 2
2 5
2 5
2 6
输出:
Regn DocName
1 1
1 2.1
1 2.2
2 5.1
2 5.2
2 6
您可以使用只有一个项目的LINQ和cast out组进行分组,然后迭代每个组中的项目以设置
DocName
:
// Group and filter
var groups = items.GroupBy(i => new { i.Regn, i.DocName })
.Where(g => g.Count() > 1);
// Iterate over each group with many items
foreach (var g in groups) {
var itemsInGroup = g.ToArray();
// Iterate over the items and set DocName
for (var i = 0; i < itemsInGroup.Length; ++i) {
itemsInGroup[i].DocName = g.Key + "." + (i + 1);
}
}
//组和筛选器
var groups=items.GroupBy(i=>new{i.Regn,i.DocName})
其中(g=>g.Count()>1);
//使用许多项迭代每个组
foreach(组中的变量g){
var itemsInGroup=g.ToArray();
//迭代项目并设置DocName
对于(变量i=0;i
或使用LINQ语句创建新的结果集,如:
var fixedSet = from entry in existing
group entry by entry.DocName + entry.Regn into groupedEntries
let groupedEntriesAsArray = groupedEntries.ToArray()
from groupedEntry in groupedEntriesAsArray
let index = Array.IndexOf(groupedEntriesAsArray, groupedEntry)
select new Foo
{
DocName =
string.Format("{0}.{1}", groupedEntry.DocName, index + 1),
Regn =
string.Format("{0}.{1}", groupedEntry.Regn, index + 1)
};
如果您有Foo的默认构造函数,请尝试使用以下方法:
var newItems = items.
GroupBy(f => Tuple.Create(f.Regn, f.DocName)).
SelectMany(gr => gr.Count()<=1 ? gr : gr.Select((f, i) => new Foo
{
Regn = f.Regn,
DocName = f.DocName + "." + (i + 1)
}));
var newItems=items。
GroupBy(f=>Tuple.Create(f.Regn,f.DocName))。
SelectMany(gr=>gr.Count()新建Foo
{
Regn=f.Regn,
DocName=f.DocName+“+(i+1)
}));
一句话,只是为了好玩
var query = items.GroupBy(i => new { i.DocName, i.Regn })
.SelectMany(group =>
{
int itemNum = 0;
return group.Select(item =>
{
var suffix = itemNum > 0 ? ("." + itemNum) : "";
var newDocName = item.DocName + suffix;
itemNum++;
return new { item, NewDocName = newDocName };
});
});
对不起,你能稍微澄清一下你的问题吗?我不确定你想达到什么目标。可能会添加一些伪代码?@Dublicator,提供方法的输入和输出示例。@Dublicator,我更新了我的答案。我不是一个投票人,但您的代码中存在一些问题:1。不可读,2。您可以将
Select
与索引器一起使用,而不是Array.IndexOf(groupedenteriesarray,groupedEntry)
,当性能问题很重要时,您当前的方法并不好,而且它取决于类的平等实现,可能会导致不同对象的值相同。“我认为在这种情况下,麦卡姆的回答是最好的。”赛义德·阿米里:谢谢。我知道使用这种方法会带来负面影响,但我不同意这种方法的可读性。我给出这个例子是因为没有其他答案引入像linq语句这样的查询语法。以我的阅读方式,它有着完美的意义,是最具可读性的(与其他人相比)。当然,这是一种个人品味,正如您所说,这似乎是一种个人品味,但在所有情况下,点表示法更倾向于在linq中查询语法,但在某些情况下,请参阅以了解有关这方面的讨论。@Polity,您的代码足够可读,但我完全同意Saeed关于性能问题的看法。另外,我认为通过连接Regn和DocName来分组不是一个好主意。查看foo1=newfoo{Regn=“c”,DocName=“ab”}和foo2=newfoo{Regn=“bc”,DocName=“a”}。您的查询将把它们放在一个组中。
var query = items.GroupBy(i => new { i.DocName, i.Regn })
.SelectMany(group =>
{
int itemNum = 0;
return group.Select(item =>
{
var suffix = itemNum > 0 ? ("." + itemNum) : "";
var newDocName = item.DocName + suffix;
itemNum++;
return new { item, NewDocName = newDocName };
});
});