First model:
public class Group
{
public string Name { get; set; }
public string Sid { get; set; }
}
Second model:
public class GuidelinesWorkTeam
{
public int Id { get; set; }
public string Name { get; set; }
public string Sid { get; set; }
public bool Active { get; set; }
}
I have this method:
public IEnumerable<GuidelinesWorkTeam> GetWorkTeamsWhereChangeName(
IEnumerable<Group> adGroups,
IEnumerable<GuidelinesWorkTeam> gwtItems)
{
return gwtItems.Where(gwtItem => adGroups.Any(adGroup => gwtItem.Sid == adGroup.Sid && gwtItem.Name != adGroup.Name));
}
adGroups input
| Object | Name | Sid |
|---|---|---|
| [0] | WorkTeam1 | Sid1 |
| [1] | WorkTeam3 | Sid2 |
gwtItems input
| Object | Id | Name | Sid | Active |
|---|---|---|---|---|
| [0] | 1 | WorkTeam1 | Sid1 | true |
| [1] | 2 | WorkTeam2 | Sid2 | true |
desired result
| Object | Id | Name | Sid | Active |
|---|---|---|---|---|
| [0] | 2 | WorkTeam3 | Sid2 | true |
Demo is here
I need to return an IEnumerable<GuidelinesWorkTeam> (Or other IEnumerable, because I need only adGroup.Name and gwtItem.Id) element if they meet the above criteria, but replacing gwtItem.Name with adGroup.Name.
How can I do that?
CodePudding user response:
Based on my understanding of your question, I would like to propose two different approaches to solve it:
- filtering the items in
adGroupsbefore associating theadGroupsitems with thegwtItemsitems - (filtering the items in
gwtItemsas you have already done, and then) associating thegwtItemsitems with theadGroupsitems
Depending on which variable (adGroups or gwtItems) benefits most from being filtered initially, you may choose which approach fits your use case best.
Filtering the adGroups items, then associating them with the gwtItems items
Here, all applicable items from adGroups are grouped by Sid before each Sid-based grouping is associated with items from gwtItems based on the gwtItem's Sid value. After associating adGroups groupings and gwtItems with equal Sid (and unequal Name, due to the initial filtering of adGroups) using .Join(), we select each associated adGroup and gwtItem pair's adGroup.Name and gwtItem.Id in a tuple and use SelectMany() to flatten the collection (from a IEnumerable<IEnumerable< * >> to a IEnumerable< * >).
public IEnumerable<( string Name, int Id )> GetWorkTeamsWhereChangeName(
IEnumerable<Group> adGroups,
IEnumerable<GuidelinesWorkTeam> gwtItems)
{
return adGroups
.Where(adGroup => gwtItems.Any(gwtItem =>
gwtItem.Sid == adGroup.Sid &&
gwtItem.Name != adGroup.Name))
.GroupBy(adGroup => adGroup.Sid)
.Join(gwtItems,
grouping => grouping.Key,
gwtItem => gwtItem.Sid,
( grouping, gwtItem ) => grouping
.Select(adGroup => ( adGroup.Name, gwtItem.Id )))
.SelectMany(_ => _);
}
Associating the gwtItems items with the adGroups items (after filtering the gwtItems first)
Here, the items from gwtItems are first associated with the items from adGroups based on the Sid property from the respective classes, using .Join() before a tuple containing relevant information is returned from the .Join() operation; then, only the associated items that actually have different names are selected and converted to a simpler tuple.
Your original filtering should possibly be included if it is probable that it will filter out many items from gwtItems; but it shouldn't be necessary to obtain the desired result.
public IEnumerable<( string Name, int Id )> GetWorkTeamsWhereChangeName(
IEnumerable<Group> adGroups,
IEnumerable<GuidelinesWorkTeam> gwtItems)
{
return gwtItems
// Original filtering
.Where(gwtItem => adGroups.Any(adGroup =>
gwtItem.Sid == adGroup.Sid &&
gwtItem.Name != adGroup.Name))
// Association and final filtering
.Join(adGroups,
gwtItem => gwtItem.Sid,
adGroup => adGroup.Sid,
( gwtItem, adGroup ) => (
ChangedName: gwtItem.Name != adGroup.Name,
Name: adGroup.Name,
Id: gwtItem.Id))
.Where(workTeam => workTeam.ChangedName)
.Select(workTeam => ( workTeam.Name, workTeam.Id ));
}
