I have List<User>
with this dependencies:
class User
{
public string Id { get; set; }
public List<ManagerGroup> ManagerGroups { get; set; }
}
class ManagerGroup
{
public string RoleId { get; set; }
public Manager[] Managers { get; set; }
}
class Manager
{
public string Id { get; set; }
}
and want to get the Dictionary
value, where key
is unique Manager.Id
, and value
is an array of Users
who have this manager. It would be very grateful if you could add sorting by certain ManagerGroup.RoleIds
.
Fiddle for tests
2
This should do what you want:
var users = new List<User>();
var usersByManagers = users
.SelectMany(u =>
u.ManagerGroups
.SelectMany(mg => mg.Managers
.Select(m => (ManagerId: m.Id, User: u)
)
)
)
.GroupBy(mu => mu.ManagerId)
.ToDictionary(g => g.Key, g => g.Distinct().Select(v => v.User).ToArray());
We flatten out the user/manager group/manager arrays into an enumerable of ManagerId/User, group by the manager id, and then build a dictionary with a distinct list of users.
Documentation:
SelectMany
Select
GroupBy
ToDictionary
Demo (Credit to Yong Shun for the GenerateUsers
method).
4
-
Get all managers and distinct.
-
Iterate from
managers
, and filter the element from theusers
list which contains the manager’s Id in the nestedManagers
list.
var managers = users.SelectMany(x => x.ManagerGroups)
.SelectMany(x => x.Managers)
.DistinctBy(x => x.Id)
.ToList();
var managerAndAssociatedUsers = managers.ToDictionary(
k => k.Id,
v => users
.Where(x => x.ManagerGroups.Any(mg => mg.Managers.Any(m => m.Id == v.Id)))
// .Select(x => x.Id) // To only return User Id
.ToArray());
1