C# Linq 查询连接两个列表并将结果分配给新列表

发布于 2025-01-11 01:46:17 字数 1917 浏览 2 评论 0 原文

第一个模型:

public class Group
{
    public string Name { get; set; } 
    public string Sid { get; set; }
}

第二个模型:

public class GuidelinesWorkTeam
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Sid { get; set; }
    public bool Active { get; set; }
}

我有这个方法:

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

所需结果

对象 Id 名称 Sid Active
[0] 2 WorkTeam3 Sid2 true

演示是 这里

我需要返回一个 IEnumerable (或其他 IEnumerable,因为我只需要adGroup.NamegwtItem.Id) 元素(如果满足上述条件),但将 gwtItem.Name 替换为adGroup.Name

我怎样才能做到这一点?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

帅气称霸 2025-01-18 01:46:17

根据我对您问题的理解,我想提出两种不同的方法来解决该问题:

  • 先过滤 adGroups 中的项目,然后再将 adGroups 项目与 gwtItems 关联 项目
  • (按照您已经完成的方式过滤 gwtItems 中的项目,然后)将 gwtItems 项目与 adGroups 项目关联起来,

具体取决于在哪个变量(adGroupsgwtItems)从最初的过滤中获益最多,您可以选择最适合您的用例的方法。

过滤 adGroups 项目,然后将它们与 gwtItems 项目相关联

这里,adGroups 中的所有适用项目均按 Sid 在每个基于 Sid 的分组与基于 gwtItem 的 Sid 值的 gwtItems 中的项目相关联之前。将 adGroups 分组和 gwtItems 与相等的 Sid(以及不相等的 Name)关联后,由于 的初始过滤>adGroups)使用 .Join(),我们选择每个关联的 adGroup 和 gwtItem 对的 adGroup.NamegwtItem.Idtuple 并使用 SelectMany() 来展平集合(来自 IEnumerable>>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(_ => _);
}

gwtItems 项目与 adGroups 项目关联(首先过滤 gwtItems 后)

这里,来自 gwtItems 的项目是首先根据相应类的 Sid 属性,使用 .Join()adGroups 中的项目关联,然后再使用包含相关信息的元组从返回.Join() 操作;然后,仅选择实际上具有不同名称的关联项并将其转换为更简单的元组。

如果您的原始过滤可能会从 gwtItems 中过滤掉许多项目,则可能应该包含该过滤;但不一定要获得所需的结果。

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 ));
}

Based on my understanding of your question, I would like to propose two different approaches to solve it:

  • filtering the items in adGroups before associating the adGroups items with the gwtItems items
  • (filtering the items in gwtItems as you have already done, and then) associating the gwtItems items with the adGroups items

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 ));
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文