C# 基于列字段删除重复项并对其进行修改

C# 基于列字段删除重复项并对其进行修改,c#,linq,duplicate-removal,C#,Linq,Duplicate Removal,假设我们有以下列表/IEnumerable Program : CPE, ECE 旧名单: Name Assigned_Area Program Ivan Matala Mathematics CPE Ivan Matala Mathematics ECE Jeremy Cruz Science ECE Ivan Matala Science CPE NJ Aquino

假设我们有以下列表/IEnumerable

Program : CPE, ECE
旧名单:

Name            Assigned_Area    Program
Ivan Matala     Mathematics      CPE
Ivan Matala     Mathematics      ECE
Jeremy Cruz     Science          ECE
Ivan Matala     Science          CPE
NJ Aquino       Engineering      CPE
MJ Catanaoan    Engineering      ECE      
新名单:

Name            Assigned_Area    Program
Ivan Matala     Mathematics      All Programs
Jeremy Cruz     Science          ECE
Ivan Matala     Science          CPE
NJ Aquino       Engineering      CPE
MJ Catanaoan    Engineering      ECE    
基本上,我想做的是合并每个“Name”和“Assigned_Area”字段相同的记录,如果每个记录都有两个程序(在我们的例子中是“CPE”和“ECE”),那么它应该折叠成一行,其程序现在是“All programs”

我们如何使用LINQ实现它

到目前为止,我尝试的是以下不完整的代码

var newlist = oldlist.GroupBy(x => x.Assigned_Area);

基本上,我正在考虑对那些具有相同分配区域的记录进行分组,但是上面的代码是不完整的,因为它只考虑一个字段(我需要考虑2个字段,即“名称”和“asigndId区域”),然后,如果每个分组都有两个计数,如果有两个计数,则不计算。然后我将把它折叠成一个记录,并用“所有程序”替换该程序


后续问题,但与上述相关

上述问题适用于非匿名类。基本上,我真正的问题是,我有以下代码

  public IEnumerable GetOfficialList(int visitID)
        {
            db = new PACUCOADB5Entities();

            var x = (from a in db.Accreditor_Program
                     orderby a.Accreditor.Given_Name, a.Accreditor.Middle_Initial, a.Accreditor.Surname, a.Assigned_Area, a.Program.Requested_Program ascending
                     where a.Program.Visit.VisitID == visitID
                     select new
                     {
                         a.Accreditor.Title,
                         a.Accreditor.Given_Name,
                         a.Accreditor.Middle_Initial,
                         a.Accreditor.Surname,
                         a.Assigned_Area,
                         a.Program.Requested_Program
                     }).ToList();

         return x
     }
var newx = x.GroupBy(xx => new {xx.Title,xx.Given_Name,xx.Middle_Initial,xx.Surname,xx.Assigned_Area})
                .Select(xx => new {xx.Key.Title, xx.Key.Given_Name, xx.Key.Middle_Initial, xx.Key.Surname, xx.Key.Assigned_Area, xx.Count() == 2 ? "All Programs" :x.First(y => y.Title == xx.Key.Title && y.Given_Name == xx.Key.Given_Name && y.Middle_Initial == xx.Key.Middle_Initial && y.Surname == xx.Key.Surname && y.Assigned_Area == xx.Key.Assigned_Area).Requested_Program));
正如你所看到的,“x”是我的列表/IEnumerable,我正试图将相同的概念应用到我正在研究的代码中。。。基本上,我也想做同样的事情,但是我的尝试失败了,代码如下

  public IEnumerable GetOfficialList(int visitID)
        {
            db = new PACUCOADB5Entities();

            var x = (from a in db.Accreditor_Program
                     orderby a.Accreditor.Given_Name, a.Accreditor.Middle_Initial, a.Accreditor.Surname, a.Assigned_Area, a.Program.Requested_Program ascending
                     where a.Program.Visit.VisitID == visitID
                     select new
                     {
                         a.Accreditor.Title,
                         a.Accreditor.Given_Name,
                         a.Accreditor.Middle_Initial,
                         a.Accreditor.Surname,
                         a.Assigned_Area,
                         a.Program.Requested_Program
                     }).ToList();

         return x
     }
var newx = x.GroupBy(xx => new {xx.Title,xx.Given_Name,xx.Middle_Initial,xx.Surname,xx.Assigned_Area})
                .Select(xx => new {xx.Key.Title, xx.Key.Given_Name, xx.Key.Middle_Initial, xx.Key.Surname, xx.Key.Assigned_Area, xx.Count() == 2 ? "All Programs" :x.First(y => y.Title == xx.Key.Title && y.Given_Name == xx.Key.Given_Name && y.Middle_Initial == xx.Key.Middle_Initial && y.Surname == xx.Key.Surname && y.Assigned_Area == xx.Key.Assigned_Area).Requested_Program));
但是智能感知通过我发现了错误


我们如何修复它?在给定代码的情况下,如何删除重复项。谢谢

也许有更好的方法,但我的尝试如下:

Person[] r = list.GroupBy(p => new { p.Name, p.AssignedArea })
                 .Select(g => g.ToArray())
                 .Select(g => g.Length > 1
                              UpdateProgram(g.First()) :
                              g.First())
                 .ToArray();

private static Person UpdateProgram(Person p)
{
    p.Program = "All Programs";
    return p;       
}

但就我个人而言,我会使用分组表达式和正则foreach循环:

foreach (var g in list.GroupBy(p => new { p.Name, p.AssignedArea }))
{
    var p = g.First();
    if (g.Count() > 1)
    {
        p.Program = "All Programs";
    }
    yield return p;
}
这里的
实体
是具有
名称
分配区域
程序
字段(代码中没有名称)的类。所有这些都将在假定程序计数可能为1或2的情况下起作用。这将起作用:

var result = v.GroupBy(x => new { x.Name, x.Assigned_Area})
              .Select(x => new EntityName(x.Key.Name, 
                                          x.Key.Assigned_Area, 
                                          x.Count() == 2 ? "All Programs" :v.First(y => y.Name == x.Key.Name && y.Assigned_Area== x.Key.Assigned_Area).Program) );

我从字面上理解了答案,并考虑到多行具有相同名称、AsisgnedArea和程序的内容进行了更新:

list
.GroupBy(x => new { x.Name, x.Area })
.Select(g =>
    g.Select(x=>x.Programs).Distinct().Count() == 1 ?
    new Data {Name=g.Key.Name, Area=g.Key.Area, Programs=g.First().Programs} :
    new Data {Name=g.Key.Name, Area=g.Key.Area, Programs="All programs"});
您可以使用以下方法对此进行测试:

public struct Data
{
    public string Name;
    public string Area;
    public String Programs;
}

void Main()
{
    var list= new List<Data>()
    { 
        new Data(){ Name="Ivan Matala", Area = "Mathematics", Programs = "CPE" },
        new Data(){ Name="Ivan Matala", Area = "Mathematics", Programs = "ECE" },
        new Data(){ Name="Jeremy Cruz", Area = "Science", Programs = "ECE" },
        new Data(){ Name="Ivan Matala", Area = "Science", Programs = "CPE" },
        new Data(){ Name="NJ Aquino", Area = "Engineering", Programs = "CPE" },
        new Data(){ Name="MJ Catanaoan", Area = "Engineering", Programs = "ECE" },
        new Data(){ Name="MJ Catanaoan", Area = "Science", Programs = "CPE" },
        new Data(){ Name="MJ Catanaoan", Area = "Science", Programs = "CPE" }
    };
}
公共结构数据
{
公共字符串名称;
公共区域;
公共字符串程序;
}
void Main()
{
var list=新列表()
{ 
新数据({Name=“Ivan Matala”,Area=“Mathematics”,Programs=“CPE”},
新数据({Name=“Ivan Matala”,Area=“Mathematics”,Programs=“ECE”},
新数据(){Name=“Jeremy Cruz”,Area=“Science”,Programs=“ECE”},
新数据(){Name=“Ivan Matala”,Area=“Science”,Programs=“CPE”},
新数据(){Name=“NJ Aquino”,Area=“Engineering”,Programs=“CPE”},
新数据(){Name=“MJ Catanaoan”,Area=“Engineering”,Programs=“ECE”},
新数据(){Name=“MJ Catanaoan”,Area=“Science”,Programs=“CPE”},
新数据(){Name=“MJ Catanaoan”,Area=“Science”,Programs=“CPE”}
};
}

Name要求如何?分组+foreach循环的偏好是由于性能原因还是可读性?@shree.pat18:Pure LINQ在没有赋值的情况下运行良好。正如您在其他答案中所看到的,它引入了混乱,恶化了可读性,从而降低了可维护性。只需在select中创建匿名类。新的{g.Key.Name,g.Key.AssignedArea,g.Count()==1?g.Single():“所有程序”}。你能看看这个吗?谢谢我试过你的代码,但智能感知说,哦,当然。应该是
new{g.Key.Name,g.Key.Assigned_区域,Program=g.Count()==1?g.Single()。Program:“所有程序”}
。必须为匿名类的字段命名。@Shree,我在更新问题时使用了您的代码,概念相同,但情况不同。可能出了什么问题?感谢我的
Select
实际上调用了类构造函数,而您又在创建一个匿名对象。我想这就是原因。