【问题标题】:How can I intersect two different .NET lists by a single property?如何通过单个属性将两个不同的 .NET 列表相交?
【发布时间】:2014-04-21 21:21:21
【问题描述】:

我正在尝试根据第二个 Baa 列表中的一些值过滤我的第一个 Foo 列表。

例如。

这里是an example I put up on .NET Fiddle ...

var foos = new List<Foo>
{
    new Foo { Name = "Leia" },
    new Foo { Name = "Han Solo" },
    new Foo { Name = "Chewbacca" },
    new Foo { Name = "Luke" },
};

    var baas = new List<Baa>
{
    new Baa { Alias = "aaaaa" },
    new Baa { Alias = "bbbb" },
    new Baa { Alias = "Leia" },
    new Baa { Alias = "Luke" }
};

// Expected output:
// List<Foo> results = Foo { "Leia" } and Foo { "Luke" };

查看我的要求:通过第二个列表 Alias 属性过滤第一个列表(按 Name)。

这将返回一个包含 2 个结果的 Foo 列表?

有什么线索吗?

【问题讨论】:

  • 如果您的集合包含很多项目,使用HashSet 而不是List 可能是明智的。检查HashSet中是否包含项目是一个O(1)操作,可以大大提高计算交集的速度。在HashSet 类中有一个专门的方法,参见:msdn.microsoft.com/en-us/library/vstudio/…
  • 非常好点@Benlitz!在我的场景中,每个列表将只有几个项目。但是答案确实对我将来可能需要处理列表交叉点的开发有帮助。如果两个集合是HashSet's,我希望看到一些使用Intersects 关键字的示例代码。
  • @Pure.Krome 你不能使用Intersect,因为列表有两种不同的类型。
  • 啊! HashSet 反对两个相同类型的。明白了。
  • 是的,我误读了这个问题,但是如果您使用 HashSet&lt;object&gt; 并提供您自己的 IEqualityComparer 实现,可以比较 Foos 和 Baas,您仍然可以这样做。但这会导致代码不安全,因此只有在您遇到真正的性能问题并且尽可能以最内部/私密的方式时才应该这样做。我测试了两个包含 10000 个项目的集合,使用列表获得 1400 毫秒,使用哈希集获得 pastebin.com/E6SJRDnr

标签: c# .net


【解决方案1】:

你可以在baas列表中使用Any

foos.Where(f => baas.Any(b => b.Alias == f.Name));

或者使用连接(查询语法更简洁):

var query = 
    from f in foos
    join b in baas on f.Name equals b.Alias
    select f;

Here's the code 在完整的 .NET Fiddle 中。

【讨论】:

    【解决方案2】:

    你可以使用Join:

    var results = foos.Join(baas, f => f.Name, b => b.Alias, (f, b) => f);
    

    类似于this answer

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多