2011-11-02 31 views
5

Tôi có phần thưởng lớp mà tôi giữ tiền của người dùng cho mỗi trò chơi. Tôi có hai danh sách bằng cách nào đó tôi cần phải concate. Tôi viết danh sách mẫu và kết quả mong muốn bên dưới.Hợp nhất hai danh sách dựa trên khóa C#

public class Reward 
{ 
    public int Game { get; set; } 
    public int User { get; set; } 
    public int Money { get; set; } 

    public Reward Merge(Reward p) 
    { 
     return new Reward { Game = this.Game, User = this.User, Money = this.Money + p.Money}; 
    } 
} 

    IList<Reward> list1 = new List<Reward>(); 
    list1.Add(new Reward {Game = 1, User = 1, Money = 10}); 
    list1.Add(new Reward { Game = 1, User = 2, Money = 20 }); 
    list1.Add(new Reward { Game = 1, User = 3, Money = 30 }); 


    IList<Reward> list2 = new List<Reward>(); 
    list2.Add(new Reward { Game = 2, User = 1, Money = 15 }); 
    list2.Add(new Reward { Game = 2, User = 2, Money = 25 }); 
    list2.Add(new Reward { Game = 2, User = 4, Money = 35 }); 

Bảng huy chương nên

User Money 
1 25 
2 45 
3 30 
4 35 

tôi cố gắng

IList<Reward> listConcat = list1.Concat(list2) 
       .GroupBy(u=> u.User) 
       .Select(???) 
       .ToList(); 

nhưng làm thế nào?

Trả lời

4

Bạn đã đi đúng hướng với groupby, điều này sẽ thực hiện công việc:

IEnumerable<Reward> result = 
    from r in list1.Concat(list2) 
    group r by r.User into groupedRewards 
    select new Reward 
    { 
     Game = 0, //what game to use? 
     User = groupedRewards.Key, 
     Money = groupedRewards.Sum(r => r.Money) 
    }; 

EDIT: Điều tương tự với biểu thức lambda:

IEnumerable<Reward> result = list1.Concat(list2) 
    .GroupBy(u => u.User) 
    .Select(g => new Reward 
    { 
     Game = 0, //what game to use? 
     User = g.Key, 
     Money = g.Sum(r => r.Money) 
    }); 
+0

+1 chỉ để làm cho nó dễ đọc hơn phần còn lại –

0

Vui lòng thay đổi dòng:

return new Reward { Game = this.Game, User = this.User, Money = this.Money + p.User 

để

return new Reward { Game = this.Game, User = this.User, Money = this.Money + p.Money 
0

Điều này không đẹp lắm, nhưng nó hoạt động.

var listConcat = list1.Concat(list2) 
       .GroupBy(u=> u.User) 
       .Select(rewards => new Reward { 
               User = rewards.Key, 
               Money = rewards.Select(reward => reward.Money).Sum() 
               } 
         ) 
       .ToList(); 
0

Với .GroupBy, bạn sẽ có được một danh sách các IGrouping, vì vậy chọn là như vậy:

IEnumerable<Reward> listConcat = list1.Concat(list2) 
           .GroupBy(x => x.User) 
           .Select(x => new Reward { User= x.Key, Money=x.Sum(y => y.Money) }); 
0

Tôi tưởng tượng một câu trả lời gần với những gì bạn đang tìm kiếm vẻ như thế này:

var catList = list1.Concat(list2) 
        .GroupBy (x => x.User) 
        .Select (y => new Reward{Game = 0, Money = y.Sum (z => z.Money), 
           User = y.Key}) 
        .ToList(); 

Khi trò chơi được sử dụng, bạn có thể cân nhắc lựa chọn ẩn danh (ví dụ:

.Select(new {Money = y.Sum (z => z.Money), User = y.Key}) 

Điều này sẽ cung cấp cho bạn một loại ẩn danh chứa thông tin bạn muốn sử dụng. Tuy nhiên, nếu bạn định chuyển nó ra khỏi phương pháp, thực hành tốt nhất là cung cấp cho nó một loại hoặc chỉ hiểu rằng trò chơi 0 là siêu của tất cả các trò chơi.

0
IList<Reward> listConcat = list1.Concat(list2) 
       .GroupBy(person => person.User) 
       .Select(group => group.Aggregate((rewardone, rewardtwo) => rewardone.Merge(rewardtwo))) 
       .ToList(); 
Các vấn đề liên quan