【问题标题】:Check if list<t> contains any of another list检查 list<t> 是否包含任何其他列表
【发布时间】:2012-06-21 00:25:51
【问题描述】:

我有一个这样的参数列表:

public class parameter
{
    public string name {get; set;}
    public string paramtype {get; set;}
    public string source {get; set;}
}

IEnumerable<Parameter> parameters;

还有一个我想检查的字符串数组。

string[] myStrings = new string[] { "one", "two"};

我想遍历参数列表并检查源属性是否等于任何 myStrings 数组。我可以用嵌套的 foreach 来做到这一点,但我想学习如何以更好的方式做到这一点,因为我一直在玩 linq 并且喜欢可枚举的扩展方法,比如 where 等,所以嵌套的 foreach 感觉不对。是否有更优雅的首选 linq/lambda/delete 方式来执行此操作。

谢谢

【问题讨论】:

    标签: c# list loops c#-4.0 subset


    【解决方案1】:

    如果两个列表都太大,当我们使用 lamda 表达式时,那么它会花费很长时间来获取。在这种情况下最好使用 linq 来获取参数列表:

    var items = (from x in parameters
                    join y in myStrings on x.Source equals y
                    select x)
                .ToList();
    

    【讨论】:

      【解决方案2】:

      这是一个示例,用于查找另一个列表中是否存在匹配元素

      List<int> nums1 = new List<int> { 2, 4, 6, 8, 10 };
      List<int> nums2 = new List<int> { 1, 3, 6, 9, 12};
      
      if (nums1.Any(x => nums2.Any(y => y == x)))
      {
          Console.WriteLine("There are equal elements");
      }
      else
      {
          Console.WriteLine("No Match Found!");
      }
      

      【讨论】:

      • 请注意,如果涉及的列表很大,这最终会比Intersect 方法慢很多,因为它的列表大小为 O(N*M)。 (不过在内存中是 O(1)。)
      【解决方案3】:

      您可以使用嵌套的Any() 进行此检查,该检查可在任何Enumerable 上使用:

      bool hasMatch = myStrings.Any(x => parameters.Any(y => y.source == x));
      

      在更大的集合上执行更快的是将parameters 投影到source,然后使用Intersect,它在内部使用HashSet&lt;T&gt;,所以第一种方法而不是 O(n^2)(相当于两个嵌套循环)你可以在 O(n) 中进行检查:

      bool hasMatch = parameters.Select(x => x.source)
                                .Intersect(myStrings)
                                .Any(); 
      

      此外,您应该将类​​名和属性名大写以符合 C# 样式指南。

      【讨论】:

      • 感谢似乎是我正在寻找的东西,我会尝试一下。需要更多地玩弄事物的功能方面。关于大写类和属性,我只是在写上面的例子时忘记了。
      • 为什么是 O(n^2)?不是 O(n*m) 因为我们谈论的是两个变量而不是一个变量吗?由于 m(参数)是一个常数,因此它与 O(n) 相同。我看不出在这里相交应该更快吗?但同意,Intersect 有可能更快,但不能保证。
      • 你是对的,它应该是 O(n*m) - 虽然 m 不是一个常数 - 它是列表之一的大小,即使在给定的特定示例中它可能是“ 2"。即使是常数值在实践中也不能忽略 - 对于所有非平凡的列表长度,Intersect 会更快 - 如果列表非常短,则无论哪种方式都无关紧要(在这种情况下,性能可能不是您关心的问题无论如何)
      • 如何找出条件为真的列表索引?我有一个带有句子的列表。我有一个包含特定单词的数组。如果句子中至少有一个单词,我想要列表的索引。 @BrokenGlass
      • 性能方面,parameters.Any(x =&gt; myStrings.Contains(x.source)); 不会比你的第一个例子更好吗?
      猜你喜欢
      • 2018-01-03
      • 1970-01-01
      • 2011-08-17
      • 1970-01-01
      • 2020-08-18
      • 1970-01-01
      • 2022-01-09
      • 2012-01-14
      相关资源
      最近更新 更多