2

I have a list of users as given below:

List<User> users = new List<User>();

users.Add(new User(){ UserId = "11", City = "London" });
users.Add(new User(){ UserId = "12", City = "London" });
users.Add(new User(){ UserId = "12", City = "London" });
users.Add(new User(){ UserId = "11", City = "Newyork" });
users.Add(new User(){ UserId = "14", City = "Virginia" });

Here, I want to get distinct UserIDs those have different City by C# lambda expression

So, in above case I should get a List<string> which will only contains UserId = 11 item because UserId is same but city is different for both the item.

Could you please let me know how would I do this by C# lambda code.

Thanks in advance.

nunu
  • 3,184
  • 10
  • 43
  • 58

3 Answers3

8

Something like:

var result = users.GroupBy(u => u.UserId)
                  .Where(g => g.Select(u => u.City).Distinct().Count() > 1)
                  .Select(g => g.Key)
                  .ToList();

should do it.

It takes the {UserId,City} pairs and converts into groups of those pairs indexed by UserId; and then looks for cases where there is more than one city in the group. Finally taking the key from the groups for the result.

Richard
  • 106,783
  • 21
  • 203
  • 265
  • Hi Richard... Now I want to get reverse scenarios... I want to select only those UserIds whose have single or multiple SIMILAR cities... Could you please tell me how would I do it?? Thanks in advance! – nunu Aug 29 '12 at 12:02
  • 1
    @nunu For the single city change the `> 1` condition to `== 1`. For *similar* you'll need to replace the `Distinct` with something that works with whatever you mean by similar (this might be a custom [`IEqualityComparer`](http://msdn.microsoft.com/en-us/library/bb338049.aspx) passed to `Enumerable.Distinct`'s overload). Without a specific definition of similar it is too ambiguous to be more specific. – Richard Aug 29 '12 at 14:12
  • Richard do you have an example of how to pass a lambda/anonymous function to Enumerable.Distinct? I.e. like [this](http://stackoverflow.com/a/10476426/575530) but without the separate method. – dumbledad Dec 10 '12 at 17:21
  • 1
    @dumbledad Unfortunatelly you cannot. [`Enumerable.Distinct`](http://msdn.microsoft.com/en-gb/library/bb338049.aspx) takes a [`IEqualityComparer`](http://msdn.microsoft.com/en-gb/library/ms132151.aspx) rather than a delegate. And there is no way to create an implementation of an interface with a delegate (whether another function or lambda): you have to have a type. It should be possible to create a helper type that implements `IEqualityComparer` based on a key extraction delegate without too much difficulty (but too long to write here with the limited formatting options available). – Richard Dec 11 '12 at 10:48
1
from u in users group u.City by u.UserId into grp //group on the id
where grp.Distinct().Count() > 1 // we only want those with more than one distinct city
select grp.Key //we want the key
Jon Hanna
  • 110,372
  • 10
  • 146
  • 251
  • Your answer is absolutely perfect !! Just the different is Lambda and LINQ :) I upvoted too.. – nunu Aug 29 '12 at 11:24
0
var list = users.GroupBy(Obj=>new {Obj.UserID,Obj.City}).Distinct();
Druid
  • 6,423
  • 4
  • 41
  • 56
Sanjay Gupta
  • 186
  • 2
  • 11