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 };
                });
        });