Group objects in List<T> by id and order the List by duplicateCount for each object
I have multiple List with objects. But some of the items in one list, also exists in other lists. My question is how can I merge all the items of all the lists into one final list. 开发者_运维技巧So there are no duplicates in that list and the items are sorted on the number of duplicates each item had in the different lists.
Example
List1: [users1, user2, user3, user4]
List2: [user2, user4, user5] List3: [user4,user6]result: [user4, user2, user1, user3, user5, user6]
(the order of users with the same count doesn't matter)
I tried something like this:
List<User> finalResults = list1.Concat(list2).ToList<User>();
var q = finalResults.GroupBy(x => x.id)
.Select(g => new User { name = g.First().name, count = g.Count() })
.OrderByDescending(usr => usr.count);
finalResults = q.ToList<User>();
but the result is an empty list.
Thanks in advance!
This will work like you requested:
var list1 = new[] { "u1", "u2", "u3", "u4" };
var list2 = new[] { "u2", "u4", "u5" };
var list3 = new[] { "u4", "u6" };
var allLists = list1.Concat(list2).Concat(list3);
var result = from u in allLists
group u by u into g
orderby g.Count() descending
select g.Key;
And a version with an object instead of string
var list1 = new[] { new User("u1"), new User("u2"), new User("u3"), new User("u4") };
var list2 = new[] { new User("u2"), new User("u4"), new User("u5") };
var list3 = new[] { new User("u4"), new User("u6") };
var allLists = list1.Concat(list2).Concat(list3);
var result = from u in allLists
group u by u.Name into g
orderby g.Count() descending
select g.Key;
Edit: Updated code samples projecting g.Key
instead of only g
.
And here is the Method Chain equivalent of the query above:
var result = allLists
.GroupBy(u => u.Name)
.OrderByDescending(g => g.Count())
.Select(g => g.Key);
Done with strings, but should also work with objects:
var l = new string[] { "user1", "user2", "user3", "user4",
"user2", "user4", "user5" ,
"user4", "user6" };
var result = l.Aggregate(new Dictionary<string, int>(),
(res, user) =>
{ // create a dictionary of all users and their occurence
if (!res.ContainsKey(user)) res[user] = 0;
res[user]++;
return res;
}).OrderByDescending(kvp => kvp.Value) // order by incidence
.Select(kvp => kvp.Key); // select user names only
foreach (var user in result) Console.WriteLine(user);
Try This
var result = list1.Union(list2).Union(list3).ToList();
精彩评论