C# linq Groupby是一个列表;“子列表”;
我有一个C# linq Groupby是一个列表;“子列表”;,c#,linq,C#,Linq,我有一个列表(一个条形嵌套),每个嵌套中都有一个详细信息列表。 所有这些条都是唯一的,因为其中每个元素的ID都是唯一的 现在,我想添加一个复选框,以便对内部具有相同详细信息列表的所有栏进行分组(内部的项目列表是相同的,除了它们的ID和一些我首先设置为-1或“”的参数)。以下是我为此所做的功能: private List<Meb> GroupIdenticalMeb(List<Meb> mebInput) { List<Meb> retour = new
列表
(一个条形嵌套),每个嵌套中都有一个详细信息列表。所有这些条都是唯一的,因为其中每个元素的ID都是唯一的 现在,我想添加一个复选框,以便对内部具有相同详细信息列表的所有栏进行分组(内部的项目列表是相同的,除了它们的ID和一些我首先设置为-1或“”的参数)。以下是我为此所做的功能:
private List<Meb> GroupIdenticalMeb(List<Meb> mebInput)
{
List<Meb> retour = new List<Meb>();
foreach(Meb mebOri in mebInput)
{
Meb meb = new Meb();
meb.ID = -1;
meb.Number = mebOri.Number;
meb.Length = mebOri.Length;
meb.Quantity=mebOri.Quantity;
foreach(Repere repOri in mebOri.ListReperes)
{
Repere rep = new Repere();
rep.Name = repOri.Name;
rep.Quantite = repOri.Quantite;
rep.ID = -1;
meb.ListReperes.Add(rep);
}
retour.Add(meb);
}
retour = retour.GroupBy(l => l.ListReperes)
.Select(cl => new Meb
{
ID=-1,
Number = cl.First().Number,
Length = cl.First().Length,
Quantity=cl.Sum(c => c.Quantity),
ListReperes = cl.First().ListReperes,
}).ToList();
return retour;
}
private List GroupIdenticalMeb(List-mebInput)
{
List retour=新列表();
foreach(Meb mebOri在mebInput中)
{
Meb Meb=新Meb();
meb.ID=-1;
meb.编号=mebOri.编号;
meb.长度=mebOri.长度;
meb.数量=mebOri.数量;
foreach(在mebOri.ListRepores中的repore)
{
repre=新的repre();
代表名称=报告名称;
代表数量=报告数量;
rep.ID=-1;
meb.ListReques.Add(代表);
}
添加(meb);
}
retour=retour.GroupBy(l=>l.listremes)
.选择(cl=>新Meb
{
ID=-1,
Number=cl.First().Number,
长度=cl.First().长度,
数量=总数量(c=>c数量),
ListRepreses=cl.First().ListRepreses,
}).ToList();
回归回归;
}
其想法是:
第一:我创建了一个新的列表
,该列表复制了原始的列表
,对于列表
,我也复制了它,但将ID设置为“-1”,因为其他属性在它们之间可能有所不同
第二:我在列表中创建了一个分组
但最终没有完成groupby,并且输出与输入保持相同
编辑:
我更好地解释了我的对象的结构,因为它似乎不够清晰:
每个Meb对象表示一个梁,每个梁包含REPRE对象(细节),这些细节有很多参数,最重要的是ID、名称、数量、具体示例:
ID Name Quantity
Meb1(Quantity1) contains : 11 Repere1 2
20 Repere2 1
25 Repere3 1
Meb2(Quantity2) contains : 12 Repere1 2
24 Repere2 2
28 Repere3 1
Meb3(Quantity3) contains : 31 Repere1 2
18 Repere2 1
55 Repere3 1
So I import my List<Meb>, and I want to group all my Mebs, comparing their details list.
In that case the result would be :
Meb1(Quantity4) contains : 0 Repere1 2
0 Repere2 1
0 Repere3 1
Meb2(Quantity2) contains : 0 Repere1 2
0 Repere2 2
0 Repere3 1
ID名称数量
Meb1(数量1)包含:11.2
20剧目21
25表3 1
Meb2(数量2)包含:12
24剧目22
28表3 1
Meb3(数量3)包含:31.2
18剧目21
55表3 1
所以我导入我的列表,我想对我所有的MEB进行分组,比较它们的详细信息列表。
在这种情况下,结果将是:
Meb1(数量4)包含:0.2
0剧目2 1
0 3 1
Meb2(数量2)包含:0.2
0剧目22
0 3 1
我建议您在Meb类中添加某种属性,对所有ListReselles项进行散列,然后将其分组
您可以查看此链接:
也就是说,你会:
retour=retour.GroupBy(l=>l.hashresues),这将为您的列表提供一个唯一的分组列表
其中HashReques是提供Reques列表哈希的属性。我建议您在Meb类中添加某种属性,对所有ListReques项目进行哈希,然后将其分组
您可以查看此链接:
也就是说,你会:
retour=retour.GroupBy(l=>l.hashresues),这将为您的列表提供一个唯一的分组列表
其中,HashReques是提供保留列表哈希的属性。使用IEquatable。然后可以使用标准的linq GroupBy()。请参阅下面的代码
public class Meb : IEquatable<Meb>, INotifyPropertyChanged
{
public int ID { get; set; }
public int Number { get; set; }
public int Length { get; set; }
public int Quantity { get; set;}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(string propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
private List<Meb> GroupIdenticalMeb(List<Meb> mebInput)
{
return mebInput.GroupBy(x => x).Select(x => new Meb() {
ID = x.First().ID,
Number = x.First().Number,
Length = x.First().Length,
Quantity = x.Sum(y => y.Quantity)
}).ToList();
}
public bool Equals(Meb other)
{
if ((this.Number == other.Number) && (this.Length == other.Length) && (this.Quantity == other.Quantity))
{
return true;
}
else
{
return false;
}
}
public override int GetHashCode()
{
return ID;
}
}
公共类Meb:IEquatable,iNotifyProperty已更改
{
公共int ID{get;set;}
公共整数{get;set;}
公共整数长度{get;set;}
公共整数数量{get;set;}
公共事件属性更改事件处理程序属性更改;
私有void NotifyPropertyChanged(字符串propertyName=“”)
{
if(PropertyChanged!=null)
{
PropertyChanged(这是新的PropertyChangedEventArgs(propertyName));
}
}
私有列表组标识栏(列表输入)
{
返回mebInput.GroupBy(x=>x){
ID=x.First().ID,
Number=x.First().Number,
长度=x.First().Length,
数量=x.总和(y=>y.数量)
}).ToList();
}
公共布尔等于(Meb其他)
{
if((this.Number==other.Number)&&&(this.Length==other.Length)&&(this.Quantity==other.Quantity))
{
返回true;
}
其他的
{
返回false;
}
}
公共覆盖int GetHashCode()
{
返回ID;
}
}
如果您不想使用IEquatable,请使用此
private List<Meb> GroupIdenticalMeb(List<Meb> mebInput)
{
return mebInput.GroupBy(x => new { number = x.Number, len = x.Length }).Select(x => new Meb()
{
ID = x.First().ID,
Number = x.Key.number,
Length = x.Key.len,
Quantity = x.Sum(y => y.Quantity)
}).ToList();
}
private List GroupIdenticalMeb(List-mebInput)
{
返回mebInput.GroupBy(x=>new{number=x.number,len=x.Length})
{
ID=x.First().ID,
Number=x.Key.Number,
长度=x.Key.len,
数量=x.总和(y=>y.数量)
}).ToList();
}
要比较列表,请使用以下内容
public class MyClassA : IEquatable<List<MyClassB>>
{
public List<MyClassB> myClassB { get; set; }
public bool Equals(List<MyClassB> other)
{
if(other == null) return false;
if (this.myClassB.Count() != other.Count()) return false;
var groupThis = this.myClassB.OrderBy(x => x.propertyA).ThenBy(x => x.propertyB).GroupBy(x => x).ToList();
var groupOther = other.OrderBy(x => x.propertyA).ThenBy(x => x.propertyB).GroupBy(x => x).ToList();
if (groupThis.Count() != groupOther.Count) return false;
for (int i = 0; i < groupThis.Count(); i++)
{
if (groupThis[i].Count() != groupOther[i].Count()) return false;
}
return true;
}
public override int GetHashCode()
{
return 0;
}
}
public class MyClassB : IEquatable<MyClassB>
{
public int propertyA { get; set; }
public string propertyB { get; set; }
public bool Equals(MyClassB other)
{
if (other == null) return false;
if ((this.propertyA == other.propertyA) && (this.propertyB == other.propertyB))
{
return true;
}
else
{
return false;
}
}
public override int GetHashCode()
{
return 0;
}
}
公共类MyClassA:IEquatable
{
公共列表myClassB{get;set;}
公共布尔等于(列出其他)
{
if(other==null)返回false;
if(this.myClassB.Count()!=other.Count())返回false;
var groupThis=this.myClassB.Orde
private List<Meb> GroupIdenticalMeb(List<Meb> mebInput)
{
List<Meb> retour = new List<Meb>();
foreach(Meb mebOri in mebInput)
{
Meb meb = new Meb();
meb.ID = -1;
meb.Number = mebOri.Number;
meb.Length = mebOri.Length;
meb.Quantity=mebOri.Quantity;
foreach(Repere repOri in mebOri.ListReperes)
{
Repere rep = new Repere();
rep.Name = repOri.Name;
rep.Quantite = repOri.Quantite;
rep.ID = -1;
meb.ListReperes.Add(rep);
}
retour.Add(meb);
// Here I added a string property, in which I concatenate
//name and quantity of each Repere in my List<Repere>,
//so on the end the "SomeString" parameters will be identical
//for all Meb that have the same List<Repere> (ignoring the IDs).
foreach(Meb meb in retour)
{
meb.SomeString = "";
foreach(RepereNest rep in meb.ListReperes)
{
meb.SomeString += rep.Name + rep.Quantite;
}
}
}
retour = retour.GroupBy(l => l.SomeString)
.Select(cl => new Meb
{
ID=-1,
Number = cl.First().Number,
SomeString=cl.First().SomeString,
Length = cl.First().Length,
Quantity=cl.Sum(c => c.Quantity),
ListReperes = cl.First().ListReperes,
}).ToList();
return retour;
}