【问题标题】:Finding the list of common objects between two lists查找两个列表之间的公共对象列表
【发布时间】:2014-05-21 20:46:59
【问题描述】:

我有一个类的对象列表,例如:

class MyClass
{  
   string id,
   string name,
   string lastname
}

例如:List<MyClass> myClassList;

而且我还有一些 id 的字符串列表,例如:

List<string> myIdList;

现在我正在寻找一种方法来接受这两个作为参数并返回对象的List&lt;MyClass&gt;,它们的id 与我们在myIdList 中的对象相同。

注意:较大的列表始终是 myClassList,而 myIdList 始终是其中较小的子集。 我们怎样才能找到这个交叉点?

【问题讨论】:

  • 作为一个小提示:这里的 ideal 选项是已经在 Dictionary&lt;string, MyClass&gt; 中索引了数据。有没有机会存在这样的事情?如果索引尚不存在,则不值得创建索引的开销,但如果存在:它可以使用

标签: c# linq


【解决方案1】:

所以您要查找myClassList 在哪里 myIdList 包含 ID 中的所有元素?这表明:

var query = myClassList.Where(c => myIdList.Contains(c.id));

请注意,如果您可以使用 HashSet&lt;string&gt; 而不是 List&lt;string&gt;,则每个 Contains 测试可能会更有效 - 当然如果您的 ID 列表变大的话。 (如果 ID 列表很小,则可能差别很小。)

myClassListmyIdList 中存在重复元素时,请务必考虑连接与上述方法之间的区别。连接将产生每个匹配对 - 以上将产生 myClassList 中的每个项目 0 或 1 个元素。

你想要哪些取决于你。

编辑:如果您正在与数据库交谈,最好不要首先为实体使用List&lt;T&gt; - 除非您需要它们用于其他用途,否则它会是 在数据库中进行查询比获取所有数据然后在本地执行查询更明智。

【讨论】:

  • 加入是自然的方式;您可以使用 HashSet 获得性能优势,而无需将 myIdList 设为 Hashset
  • @ThomasLevesque 我不同意 - 连接具有不同的语义(重复)。 “包含”更自然地映射到这里的规范,IMO。
  • 谢谢先生,所以我有一个 EF 对象,它返回我一个列表,假设数据库中的所有教师,然后我有一些这些教师的一些 ID 的列表和我想要一个教师对象列表,但不是所有对象,即他们的 ID 在该 ID 列表中的对象。
  • @DevWannaBe:好的,那么您将我的答案(或任何其他答案)中的代码翻译到您的应用程序中有什么困难?请注意,最好在数据库中进行查询,而不是先提取整个组教师。
  • @DevWannaBe:这一切都取决于细节 - 如果你有一个非常小的数据集,那么将它们全部缓存在内存中可能是有意义的 - 但如果你'正在要求(比如说)1000 万个元素中的 10 个元素,那么您不想获取所有 1000 万个元素,而只是将其中的大部分扔掉。
【解决方案2】:

这不是严格意义上的交集(除非 id 是唯一的),但您可以简单地使用 Contains,即

var sublist = myClassList.Where(x => myIdList.Contains(x.id));

但是,如果您先创建 HashSet&lt;T&gt;,您将获得明显更好的性能:

var hash = new HashSet<string>(myIdList);
var sublist = myClassList.Where(x => hash.Contains(x.id));

【讨论】:

    【解决方案3】:

    您可以在两个列表之间使用连接:

    return myClassList.Join(
            myIdList,
            item => item.Id,
            id => id,
            (item, id) => item)
        .ToList();
    

    【讨论】:

    • 这会在后台创建一个哈希列表吗?只是好奇它与在性能方面给出的其他选项相比如何......
    • @Chris,我不知道确切的实现,但是是的,我相信它在某些时候使用了 HashSet (或类似的东西)。你可以在这里查看实现:referencesource.microsoft.com/#System.Core/System/Linq/…
    【解决方案4】:

    它是两个列表之间的一种交集,所以阅读它就像我想要一个列表中存在的第二个列表中的东西一样。这里 ToList() 部分同时执行查询。

    var lst = myClassList.Where(x => myIdList.Contains(x.id)).ToList();
    

    【讨论】:

      【解决方案5】:

      你必须使用下面提到的代码

      var samedata=myClassList.where(p=>p.myIdList.Any(q=>q==p.id))
      

      【讨论】:

        【解决方案6】:
        myClassList.Where(x => myIdList.Contains(x.id));
        

        【讨论】:

          【解决方案7】:

          试试

          List<MyClass> GetMatchingObjects(List<MyClass> classList, List<string> idList)
          {
            return classList.Where(myClass => idList.Any(x => myClass.id == x)).ToList();
          }
          

          【讨论】:

            【解决方案8】:
            var q = myClassList.Where(x => myIdList.Contains(x.id));
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2021-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-10-24
              • 1970-01-01
              • 1970-01-01
              • 2013-06-27
              相关资源
              最近更新 更多