检查 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<T>
,所以第一种方法而不是 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 => myStrings.Contains(x.source));
不会比你的第一个例子更好吗?以上是关于检查 list<t> 是不是包含任何其他列表的主要内容,如果未能解决你的问题,请参考以下文章
如何检查 List<T> 元素是不是包含具有特定属性值的项目
如何检查字符串是不是包含 List<string> 的任何元素?