8

この問題に何度も遭遇します。他のオブジェクトのリストを含むオブジェクトのリストをグループ化するにはどうすればよいですか?

タイプのオブジェクトのリストがありA、これらの各オブジェクトには、リストでもあるプロパティ(それを呼び出しましょうListProp)があります。ListPropタイプの要素がありBます。Aには同じB-objects を持つtype の要素が複数ありますListPropが、ListPropプロパティ参照は要素ごとに異なります。これらの -objects を最速の方法でグループ化Aするにはどうすればよいですか?BListProp

サンプルコード:

class Program
{
    static void Main(string[] args)
    {
        var exampleList = new List<A>
        {
            // Should be in first group
            new A { ListProp = new List<B>
            {
                new B { Prop = new C { Number = 0 }},
                new B { Prop = new C { Number = 1 }}
            }},
            // Should be in first group
            new A { ListProp = new List<B>
            {
                new B { Prop = new C { Number = 0 }},
                new B { Prop = new C { Number = 1 }}
            }},
            // Should be in second group
            new A { ListProp = new List<B>
            {
                new B { Prop = new C { Number = 0 }},
                new B { Prop = new C { Number = 1 }},
                new B { Prop = new C { Number = 1 }}
            }},
            // Should be in third group
            new A { ListProp = new List<B>
            {
                new B { Prop = new C { Number = 0 }},
                new B { Prop = new C { Number = 0 }}
            }}
        };

        // Doesn't work because the reference of ListProp is always different
        var groupedExampleList = exampleList.GroupBy(x => x.ListProp);
    }
}

class C
{
    public int Number { get; set; }
    public override bool Equals(object o)
    {
        if (o is C)
            return Number.Equals(((C)o).Number);
        else
            return false;
    }
}

class B
{
    public C Prop { get; set; }
}

class A
{
    public IList<B> ListProp { get; set; }
}
4

3 に答える 3

6

IEqualityComparer<List<B>>他の GroupBy オーバーロードで実装して使用できます。

public class ListOfBEqualityComparer : IEqualityComparer<List<B>>
{
    public bool Equals(List<B> x, List<B> y)
    {
        // you can also implement IEqualityComparer<B> and use the overload
        return x.SequenceEqual(y);
    }

    public int GetHashCode(List<B> obj)
    {
        //implementation of List<T> may not work for your situation
        return obj.GetHashCode();
    }
}

次に、オーバーロードを使用できます

var groupedExampleList = exampleList.GroupBy(x => x.ListProp, 
                                             new ListOfBEqualityComparer());
于 2012-04-20T11:09:31.840 に答える
4

これを試して:

GroupBy(x => String.Join(",", x.ListProp));

それに応じてグループ化さ0,1; 0,1; 0,1; 0,1,1; 0,1れます。

于 2012-04-20T11:09:30.043 に答える
0

私はこれに次のようにアプローチします。

  1. 各子要素 (ListProp プロパティ内) をその親に関連付けます
  2. 親を子別にグループ化する
  3. 結果を投影する

var data = exampleList.SelectMany(a=>a.ListProp.Select(x=>new{Key = x.Prop.Number, Value = a}))
           .GroupBy(x=>x.Key)
           .Select(g=>new {Number = g.Key, Items = g.ToList()});
于 2012-04-20T11:23:11.113 に答える