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