繁体   English   中英

在List中使用Linq查询 <T> .AddRange有条件地将元素从一个列表添加到另一个列表

[英]Using Linq query inside List<T>.AddRange to conditionally add elements from one list to another

我有一个List<String>和两个List<CustomObject>
我想组合两个List<CustomObject>但仅当List<String>不包含第二个List<CustomObject>属性时。

所以,想要做这样的事情:

resultSet1.AddRange(resultSet2.Select(x => !names.Contains(x.City)).ToList());

我在这里错过了什么?

当你应该使用Where时,你会误用Select

resultSet1.AddRange(resultSet2.Where(x => !names.Contains(x.City));

Select是一种投影方法。 它需要一个序列并选择它,有时选择整个项目,单个属性,或将其完全投射到其他东西。

过滤方法Where 它接受一个序列并对其应用谓词,只产生传递谓词的元素。

(在您的示例中,通过使用Select ,您有效地尝试将一个bool列表添加到CustomObject列表中,这不会起作用。)


没有解决手头的具体错误,这里有一些需要考虑的其他想法。

在这种情况下, HashSet<string>可能对names有益,特别是如果names非常大。 ContainsHashSet<T>上具有O(1)复杂度,而对于List<T>则为O(n)。 但是,HashSet会产生开销,因此如果您有任何疑虑,最好同时测量两者并查看哪些更高效。

还有一件事可能会有所帮助,如果您只需要将一个序列流式传输到另一个序列之后并且不一定需要更改或添加到任一集合,您可以考虑使用UnionConcat操作。

var sequence = resultSet1.Union(resultSet2.Where(x => !names.Contains(x.City)));
var sequence = resultSet1.Concat(resultSet2.Where(x => !names.Contains(x.City)));

两者的区别在于Union将过滤掉结果序列中的任何重复项(来自两个输入,而不仅仅是第二个与第一个相比), Concat不应用重复过滤逻辑,只是简单地将一个序列流式传输到另一个序列。 输入序列( resultSet1resultSet2 )未经修改。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM