Linqを使用してオブジェクトのリストをオブジェクトのリストの新しいグループ化されたリストにグループ化する


149

これがLinqで可能かどうかはわかりませんが、ここに行きます...

私はオブジェクトを持っています:

public class User
{
  public int UserID { get; set; }
  public string UserName { get; set; }
  public int GroupID { get; set; }
}

次のようなリストを返します。

List<User> userList = new List<User>();
userList.Add( new User { UserID = 1, UserName = "UserOne", GroupID = 1 } );
userList.Add( new User { UserID = 2, UserName = "UserTwo", GroupID = 1 } );
userList.Add( new User { UserID = 3, UserName = "UserThree", GroupID = 2 } );
userList.Add( new User { UserID = 4, UserName = "UserFour", GroupID = 1 } );
userList.Add( new User { UserID = 5, UserName = "UserFive", GroupID = 3 } );
userList.Add( new User { UserID = 6, UserName = "UserSix", GroupID = 3 } );

上記のリストで、すべてのユーザーをGroupIDでグループ化するLinqクエリを実行できるようにしたいと思います。したがって、出力はuserを含むユーザーリストのリストになります(もし意味があれば?)。何かのようなもの:

GroupedUserList
    UserList
        UserID = 1, UserName = "UserOne", GroupID = 1
        UserID = 2, UserName = "UserTwo", GroupID = 1
        UserID = 4, UserName = "UserFour", GroupID = 1
    UserList
        UserID = 3, UserName = "UserThree", GroupID = 2
    UserList
        UserID = 5, UserName = "UserFive", GroupID = 3
        UserID = 6, UserName = "UserSix", GroupID = 3

groupby linq句を使用しようとしましたが、これはキーのリストを返し、正しくグループ化されていないようです。

var groupedCustomerList = userList.GroupBy( u => u.GroupID ).ToList();

回答:


309
var groupedCustomerList = userList
    .GroupBy(u => u.GroupID)
    .Select(grp => grp.ToList())
    .ToList();

1
とてもいいです ありがとうございました。これを行うことは、命令的な方法でうまくいきません。
user1841243 2013

1
うまくいきますか?私はこの方法を使用しているので機能しませんでした。objModel.tblDonars.GroupBy(t => new {t.CreatedOn.Year、t.CreatedOn.Month、t.CreatedOn.Day})。Select(g => new {tblDonar = g.ToList()})。ToList( ); これは機能していません...助けてもらえますか?
Rajamohan Anguchamy 2014

あなたの解決策でそれはうまくいきますが、8つの値までのグループで1つの質問があると思います、6つのテイクだけですべてのグループに必要なので、それを行う方法を教えてください。
coderwill 2017年

GroupIDでグループ化した後、UserNamesとUserIDを個別にリストする方法はありますか?like-{"1"、[1、2、4]、["UserOne"、 "UserTwo"、 "UserFour"]} for groupID 1.
Ajay Aradhya

1
現在、コードは機能せず、以前のタイプのリストにキャストしようとするとエラーが発生します。selectでリストを返すと、リスト内にリストが作成されますが、ここでは目的の出力ではありません。問題がある人のために私は提案できます:var groupedCustomerList = userList.GroupBy(u => u.GroupID).Select(grp => grp.First())。ToList();
エイリアス

36

グループステートメント、グループIDでグループ化されます。たとえば、次のように書いた場合:

foreach (var group in groupedCustomerList)
{
    Console.WriteLine("Group {0}", group.Key);
    foreach (var user in group)
    {
        Console.WriteLine("  {0}", user.UserName);
    }
}

それはうまくいくはずです。各グループはキーがありますが、IGrouping<TKey, TElement>これには、グループのメンバーを反復できるコレクションであるも含まれます。Leeが言及しているように、本当に必要な場合は各グループをリストに変換できますが、上記のコードに従ってグループを反復するだけの場合、そうすることには実際的な利点はありません。


4

タイプについて

public class KeyValue
{
    public string KeyCol { get; set; }
    public string ValueCol { get; set; }
}

コレクション

var wordList = new Model.DTO.KeyValue[] {
    new Model.DTO.KeyValue {KeyCol="key1", ValueCol="value1" },
    new Model.DTO.KeyValue {KeyCol="key2", ValueCol="value1" },
    new Model.DTO.KeyValue {KeyCol="key3", ValueCol="value2" },
    new Model.DTO.KeyValue {KeyCol="key4", ValueCol="value2" },
    new Model.DTO.KeyValue {KeyCol="key5", ValueCol="value3" },
    new Model.DTO.KeyValue {KeyCol="key6", ValueCol="value4" }
};

私たちのlinqクエリは以下のようになります

var query =from m in wordList group m.KeyCol by m.ValueCol into g
select new { Name = g.Key, KeyCols = g.ToList() };

または以下のようなリストの代わりに配列

var query =from m in wordList group m.KeyCol by m.ValueCol into g
select new { Name = g.Key, KeyCols = g.ToList().ToArray<string>() };

-1

まだ古いですが、Leeからの返答は私にグループを与えませんでした。したがって、次のステートメントを使用してリストをグループ化し、グループ化されたリストを返します。

public IOrderedEnumerable<IGrouping<string, User>> groupedCustomerList;

groupedCustomerList =
        from User in userList
        group User by User.GroupID into newGroup
        orderby newGroup.Key
        select newGroup;

これで各グループにキーが追加されましたが、グループのメンバーを反復処理できるコレクションであるIGroupingも含まれています。


これはOPの質問ではなく、あなたの質問に答えます。彼らはリストのリストだけを望んでいます。あなたのコードはそれを提供していません。
Gert Arnold

@JohnSkeetの回答に示されているように、グループ化されたリストを反復するときに要素を提供しないため、@ Leeからの上記の受け入れられた回答が反復時に機能しないため、このソリューションを投稿group.keyしました。私が提供した答え、反復時にgroup.key要素を提供します。したがって、提供された回答が上記のように機能しないことは、他の罠に陥るのを助けるかもしれません。したがって、これは、受け入れられた回答と同様のgroup.key要素を取得する利点を持つリストを取得するためのもう1つの方法です。@GertArnoldの主張を理解しないでください。(.net core 3.0)
プール

問題全体は何IGroupingが何であるかを理解していないことに基づいていると思います。そのため、OPは下部にある独自の正しいコードを破棄します。これは、基本的にコードと同じです。それが彼らが彼らが求めるものを正確に提供する答えを受け入れる理由です。彼らが必要としているのは、JSが十分に提供した説明です。
Gert Arnold
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.