2

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
  • A helpful hint: Provide the sample input and expected output result and also your code attempt in the question. Commented Dec 17, 2024 at 0:54
  • It's not really clear what you mean by "sorting". The only place I feel it would make sense is to sort the managers, but a dictionary isn't an ordered collection. Commented Dec 17, 2024 at 1:26

2 Answers 2

3

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:

Demo (Credit to Yong Shun for the GenerateUsers method).

Sign up to request clarification or add additional context in comments.

4 Comments

Hi, your answer is almost perfect, a minor change in the dictionary value to return the users: g.Distinct().Select(x => x.User.Id).ToArray(). =)
@YongShun No, my answer is perfect per the question. The OP wants a map of ManagerId to User, not ManagerId to UserId.
So currently now your dictionary result will be key: ManageId and value: ValueTuple with ManagerId and User.
@YongShun Ah yes, I've fixed that now. Thanks.
2
  1. Get all managers and distinct.

  2. Iterate from managers, and filter the element from the users list which contains the manager's Id in the nested Managers 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 Comment

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.