Manish Makkad
Manish Makkad

Reputation: 237

Group by Name Linq + C#

I am new to Linq, i have following scenario.

class Program
{
    static void Main(string[] args)
    {

        var address = new List<Address>();
        address.Add(new Address { AddressLine = "Address 1", City = "City 1", State = "State 1", UserId = 1 });
        address.Add(new Address { AddressLine = "Address 1 Dup", City = "City 1", State = "State 1", UserId = 1 });
        address.Add(new Address { AddressLine = "Address 2", City = "City 2", State = "State 2", UserId = 2 });
        address.Add(new Address { AddressLine = "Address 2 Dup", City = "City 2", State = "State 2", UserId = 2 });
        address.Add(new Address { AddressLine = "Address 3", City = "City 3", State = "State 3", UserId = 1 });
        address.Add(new Address { AddressLine = "Address 3 Dup", City = "City 3", State = "State 3", UserId = 1 });

        var users = new List<User>();
        users.Add(new User { Id = 1, Name = "User 1", NickName = "user 1", Address = address });
        users.Add(new User { Id = 2, Name = "User 1", NickName = "user 2", Address = address });
        users.Add(new User { Id = 3, Name = "User 2", NickName = "user 3", Address = address });
        users.Add(new User { Id = 4, Name = "User 2", NickName = "user 4", Address = address });
    }
}

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Address> Address { get; set; }
    public string NickName { get; set; }
}

public class Address
{
    public string AddressLine { get; set; }
    public string City { get; set; }
    public string State { get; set; }

    public int UserId { get; set; }
}

I want to group User class List by user name, so if address for above example first two object with name user1 should be merged into one object. Address of both the object should be merged to one.

Upvotes: 0

Views: 410

Answers (2)

jdweng
jdweng

Reputation: 34421

Try following :

            var results = users.GroupBy(x => x.Name).Select(x => new
            {
                ids = x.Select(y => y.Id).ToList(),
                nicNames = x.Select(y => y.NickName).ToList(),
                addresses = x.Select(y => new { addresses = address.Where(z => z.UserId == y.Id) }).SelectMany(a => a.addresses).ToList()
            }).ToList();

Upvotes: 1

CodeFuller
CodeFuller

Reputation: 31282

If you need just to concatenate address lists for merged users, then this LINQ will do it:

var mergedUsers =
    from user in users
    group user by user.Name
    into newGroup
    let baseUser = newGroup.First()
    select new User
    {
        Id = baseUser.Id,
        Name = baseUser.Name,
        NickName = baseUser.NickName,
        Address = newGroup.SelectMany(u => u.Address).ToList()
    };

This code also assumes that other properties for merged users like NickName and Id are consistent (i.e. equal). The values are taken from first user in merge list.

Upvotes: 2

Related Questions