Merge two lists with C # key

I have a Reward class in which I keep user money for the game. I have two lists, somehow I need to specify. I am writing sample lists and the desired result below.

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 });

The list of results should be

User Money
1    25
2    45
3    30
4    35

I'm trying to

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

but how?

+5
source share
6 answers

You were on the right track with GroupBy, this should work:

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: Same thing with lambda expression:

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)
    });
+4
source

Change the line:

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

to

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

, .

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

.GroupBy IGrouping, :

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

, , , , :

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();

, , (,

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

This will give you an anonymous type that contains the information you want to use. However, if you are going to abandon this method, it is best to give it a type or just understand that game 0 is your superset of all games.

0
source
IList<Reward> listConcat = list1.Concat(list2)
                .GroupBy(person => person.User)
                .Select(group => group.Aggregate((rewardone, rewardtwo) => rewardone.Merge(rewardtwo)))
                .ToList();
0
source

All Articles