Utiliser LINQ pour grouper une liste d'objets

j'ai un objet:

public class Customer
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int GroupID { get; set; }
}

je retourner une liste qui peut ressembler à ce qui suit:

List<Customer> CustomerList = new List<Customer>();
CustomerList.Add( new Customer { ID = 1, Name = "One", GroupID = 1 } );
CustomerList.Add( new Customer { ID = 2, Name = "Two", GroupID = 1 } );
CustomerList.Add( new Customer { ID = 3, Name = "Three", GroupID = 2 } );
CustomerList.Add( new Customer { ID = 4, Name = "Four", GroupID = 1 } );
CustomerList.Add( new Customer { ID = 5, Name = "Five", GroupID = 3 } );
CustomerList.Add( new Customer { ID = 6, Name = "Six", GroupID = 3 } );

je veux retourner une requête linq qui ressemblera à

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

j'ai essayé de

utilisant Linq pour grouper une liste d'objets dans une nouvelle liste groupée d'objets

code

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

fonctionne, mais ne donne pas le résultat souhaité.

20
demandé sur Community 2013-09-02 06:42:20

6 réponses

var groupedCustomerList = CustomerList.GroupBy(u => u.GroupID)
                                      .Select(grp =>new { GroupID =grp.Key, CustomerList = grp.ToList()})
                                      .ToList();
59
répondu Tim.Tang 2013-09-02 02:48:59
var groupedCustomerList = CustomerList
                         .GroupBy(u => u.GroupID, u=>{
                                                        u.Name = "User" + u.Name;
                                                        return u;
                                                     }, (key,g)=>g.ToList())
                         .ToList();

si vous ne voulez pas changer les données originales, vous devez ajouter une méthode (sorte de clone et modifier) à votre classe comme ceci:

public class Customer {
  public int ID { get; set; }
  public string Name { get; set; }
  public int GroupID { get; set; }
  public Customer CloneWithNamePrepend(string prepend){
    return new Customer(){
          ID = this.ID,
          Name = prepend + this.Name,
          GroupID = this.GroupID
     };
  }
}    
//Then
var groupedCustomerList = CustomerList
                         .GroupBy(u => u.GroupID, u=>u.CloneWithNamePrepend("User"), (key,g)=>g.ToList())
                         .ToList();

je pense que vous pouvez vouloir afficher le Customer différemment sans modifier les données originales. Si tel est le cas, vous devez concevoir votre classe Customer différemment, comme ceci:

public class Customer {
  public int ID { get; set; }
  public string Name { get; set; }
  public int GroupID { get; set; }
  public string Prefix {get;set;}
  public string FullName {
    get { return Prefix + Name;}
  }            
}
//then to display the fullname, just get the customer.FullName; 
//You can also try adding some override of ToString() to your class

var groupedCustomerList = CustomerList
                         .GroupBy(u => {u.Prefix="User", return u.GroupID;} , (key,g)=>g.ToList())
                         .ToList();
4
répondu King King 2013-09-02 03:06:59
var groupedCustomerList = CustomerList
 .GroupBy(u => u.GroupID)
 .Select(g => new
             {
                 GroupId = g.Key,
                 Items = g.Select(i => new
                 {
                     UserID = i.ID,
                     UserName = string.Concat("User", i.Name),
                     GroupId = i.GroupID
                 }).ToList()
             })
.ToList();
3
répondu sa_ddam213 2013-09-02 03:06:07

c'est ça que tu veux?

var grouped = CustomerList.GroupBy(m => m.GroupID).Select((n) => new { GroupId = n.Key, Items = n.ToList() });
1
répondu Rex 2013-09-02 02:48:35

le résultat souhaité peut être obtenu en utilisant IGrouping , qui représente une collection d'objets qui ont une clé commune dans ce cas a GroupID

 var newCustomerList = CustomerList.GroupBy(u => u.GroupID)
                                                  .Select(group => new { GroupID = group.Key, Customers = group.ToList() })
                                                  .ToList();
0
répondu Bhushan Firake 2013-09-02 02:52:46
var result = from cx in CustomerList
         group cx by cx.GroupID into cxGroup
     orderby cxGroup.Key
     select cxGroup; 

foreach (var cxGroup in result) { 
Console.WriteLine(String.Format("GroupID = {0}", cxGroup.Key)); 
  foreach (var cx in cxGroup) { 
    Console.WriteLine(String.Format("\tUserID = {0}, UserName = {1}, GroupID = {2}", 
      new object[] { cx.ID, cx.Name, cx.GroupID })); 
  }
}
0
répondu jdphenix 2013-09-02 03:02:45