Use SelectMany and GroupBy
The following ProjectEnrolment defines the user in the project and his type of registration in it:
public class ProjectEnrolment {
public Project Project { get; set; }
public User User { get; set; }
public EnrolmentType EnrolmentType { get; set; }
}
For testing purposes, I need to create a list of ProjectEnrolments, where:
1. For each project there should be no more than one project;
2. The user cannot appear twice in the project.
I tried the following:
List<ProjectEnrolment> projectEnrolments =
projects.SelectMany(x =>
users.SelectMany(y =>
enrolmentTypes.Select(z =>
new ProjectEnrolment {
EnrolmentType = z,
Project = x,
User = y
})))
.GroupBy(u => u.Project)
.Select(v => v.OrderBy(w => Guid.NewGuid()).FirstOrDefault())
.ToList();
But this gives me one ProjectEnrolment for each project that I don't need.
+3
source to share
2 answers
Though it is possible I would not do what you want in one command using SelectMany
other linq methods as well. This is pretty tricky logic and the final instruction won't be readable. How about this:
Random r = new Random();
IList<ProjectEnrolment> projectEnrolments = new List<ProjectEnrolment>();
foreach (Project project in projects)
{
int firstUser = r.Next(users.Count);
projectEnrolments.Add(new ProjectEnrolment {
EnrolmentType = enrolmentTypes[r.Next(enrolmentTypes.Count)],
Project = project,
User = users[firstUser]
});
int secondUser;
do {
secondUser = r.Next(users.Count);
} while (secondUser == firstUser);
projectEnrolments.Add(new ProjectEnrolment {
EnrolmentType = enrolmentTypes[r.Next(enrolmentTypes.Count)],
Project = project,
User = users[secondUser]
});
}
Linq version
IList<ProjectEnrolment> projectEnrolments = projects.SelectMany(p => users.OrderBy(u => Guid.NewGuid()).Take(2).Select(u => new ProjectEnrolment {
EnrolmentType = enrolmentTypes.OrderBy(t => Guid.NewGuid()).FirstOrDefault(),
Project = p,
User = u
})).ToList();
+1
source to share
You can also use this one.
Here, each user will be registered for each project with a random registration type:
Random rnd = new Random();
var res = users.SelectMany(u => projects.Select(p => new ProjectEnrolment() {EnrolmentType = enrollmentTypes[rnd.Next(0, 3)], User = u, Project = p}))
.GroupBy(i => i.Project);
0
source to share