检查 list<t> 是不是包含任何其他列表

Posted

技术标签:

【中文标题】检查 list<t> 是不是包含任何其他列表【英文标题】: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 方式来执行此操作。

谢谢

【问题讨论】:

【参考方案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)); 不会比你的第一个例子更好吗?

以上是关于检查 list<t> 是不是包含任何其他列表的主要内容,如果未能解决你的问题,请参考以下文章

如何检查 List<T> 元素是不是包含具有特定属性值的项目

如何检查字符串是不是包含 List<string> 的任何元素?

List<T> 任何或计数? [复制]

检查链表<Node<T>>是不是包含某个节点

按值而不是引用将 List<T> 分配给另一个 List<T> [重复]

android mono:使用 List<T> 而不是 ArrayAdapter 来使用 Contains 方法