2013-01-28 16 views
5

Có thể không được diễn đạt hoàn toàn đúng nhưng đây là những gì tôi có và đây là kết quả mà tôi muốn đạt được:Sử dụng LINQ, làm thế nào để groupby chống lại các đối tượng trong danh sách bên trong đối tượng mục tiêu

class Cake 
{ 
public List<string> Ingrediants {get;set;} 
public DateTime Baked {get;set;} 
public string CakeName {get;set;} 
} 

List<Cake> cakes= new List<Cake>(); 
cakes.Add(new Cake() {CakeName = "Cake1", Ingrediants = new List<string>() {"Sugar", "Chocolate"}}); 
cakes.Add(new Cake() {CakeName = "Cake2", Ingrediants = new List<string>() {"Sugar", "Butter"}}); 
cakes.Add(new Cake() {CakeName = "Cake3", Ingrediants = new List<string>() {"Stevia", "Butter"}}); 

Tôi muốn nhóm bánh của ingrediant. Vì vậy, tôi muốn kết thúc với điều này:

- Sugar 
     Cake1 
     Cake2 
- Stevia 
     Cake3 
- Chocolate 
     Cake1 
- Butter 
     Cake2 
     Cake3 

Cảm ơn bạn trước!

+0

Bạn muốn gì, GroupBy hoặc OrderBy? Nó cũng không rõ ràng làm thế nào các bánh được đặt hàng. –

+0

Tôi muốn nhóm chúng bằng GroupBy trên ingrediant. Thứ tự bánh không quan trọng – Tom

Trả lời

8

Nếu bạn không nhớ comprehensions truy vấn, đây là một sự thay thế (lưu ý cách viết điều chỉnh):

IEnumerable<IGrouping<string,Cake>> query = 
    from cake in cakes 
    from ingredient in cake.Ingredients 
    group cake by ingredient; 

Surprise! Đây là một truy vấn hợp lệ! Ngôn ngữ-spec cho phép hiểu được để kết thúc với một nhóm-by. IGrouping<string,Cake> về mặt kỹ thuật là IEnumerable<Cake> có thuộc tính Key thuộc loại string - trong trường hợp này là thành phần. Trình biên dịch hoạt động để biến nó thành mã gần như giống hệt với các câu trả lời khác.

Chúng ta có thể thay đổi các truy vấn để tạo ra các loại generic tương tự giống với câu trả lời khác bằng cách giới thiệu một into và một điều khoản select mà làm việc ngoài khơi truy vấn tiếp:

var query = 
    from cake in cakes 
    from ingredient in cake.Ingredients 
    group cake by ingredient into cakesGrouped 
    select new { Ingredient = cakesGrouped.Key, 
     Cakes = cakesGrouped.ToList() }; 

Cả thạo-cú pháp và query- cú pháp đáng để biết, IMHO. Chúc mừng!

+2

+1 Tốt, cú pháp truy vấn dễ đọc hơn trong trường hợp này. – GolfWolf

4

Dưới đây là một cách để làm điều đó:

var result = cakes 
    .SelectMany(c => c.Ingrediants.Select(i => new 
     { 
      c.CakeName, 
      Ingredient = i 
     })) 
    .GroupBy(x => x.Ingredient) 
    .Select(g => new 
     { 
      Ingredient = g.Key, 
      Cakes = g.Select(x=>x.CakeName).ToArray() 
     }); 

result sẽ là một IEnumerable của một loại vô danh; một yếu tố đại diện cho một thành phần và tất cả các bánh chứa nó.

+0

Cảm ơn bạn đã nhập. Tôi đánh dấu điều này là chính xác nhưng Lee đã đánh bại bạn một phút hoặc 2. – Tom

+1

@Tom FWIW, điều đó không đúng. Khi bạn muốn tìm câu trả lời sớm nhất bằng LINQ, bạn nên thực hiện 'answers.Min (a => a.Time)', không phải 'Max' :-) – GolfWolf

6
var ingrediants = cakes.SelectMany(c => c.Ingrediants.Select(i => new { Cake = c, Ingrediant = i })) 
    .GroupBy(ci => ci.Ingrediant) 

Sau đó, khóa nhóm là tên thành phần và tập hợp nhóm là các bánh phù hợp.

Các vấn đề liên quan