"左XOR" LINQ的两个列表之间

时间:2015-06-17 12:27:54

标签: c# linq ienumerable

我必须收藏:

IEnumerable<lineResult> diplayedBondsList

List<string> pIsinList

lineResult是一个非常简单的类,定义为:

public class lineResult
{
    public string isin { get ; set ; }
    public double rate { get ; set ; }
    public string issuer { get ; set ; }
}

我正在尝试使用pIsinList中的字符串创建一个新的List,但是只有当它们不在字段中时才会出现在&#34; lineResult&#34; diplayedBondsList的元素。一种&#34;离开XOR&#34; (左边因为在另一个表中只添加了两个列表元素中的一个而没有对应关系)。

我试图不使用太多的循环,因为我的列表有非常大量的数据,我认为这会减慢程序。

我写过这个,但它似乎不起作用,newBondLines总是空的:

IEnumerable<lineResult> newBondLines = diplayedBondsList.Where(item => pIsinList.IndexOf(item.isin) < 0);

foreach (lineResult lr in newBondLines)
{
    newIsinList.Add(lr.isin);
}

另外,我确实使用了一个循环,也许我可以通过一个很好的LINQ语句来避免它。

我怎么能1)让这个&#34;离开XOR&#34;工作和2)提高其速度?

3 个答案:

答案 0 :(得分:5)

使用Enumerable.Except

List<string> xorred = pIsinList.Except(
    diplayedBondsList.Select(x => x.isin)).ToList();

请注意,此命令将在Distinct()上隐式执行pIsinList(MSDN中未对此进行解释,但如果您查看source则非常清楚),如果new[] { "A", "A" }中有pIsinList,则最终结果为"A"

您可以手动执行Except&#34;&#34;解决这个&#34;问题&#34; (如果是问题):

var set = new HashSet<string>(diplayedBondsList.Select(x => x.isin));
List<string> xorred = pIsinList.Where(x => !set.Contains(x)).ToList();

答案 1 :(得分:0)

您可以使用第二个列表中的Contains

var result = diplayedBondsList
    .Where(l => !pIsinList.Contains(l.isin))
    .Select(l => l.isin)
    .ToList();

我认为速度无法提高,因为无论采用哪种方法,您都必须将一个列表中的所有项目与另一个列表中的所有项目进行比较。即使你移除了循环,Linq也必须在引擎盖下做一个(或几个)。

答案 2 :(得分:0)

在两个列表之间存在XOR,左XOR或右XOR的扩展: https://stackoverflow.com/a/45480272/2546739

(不是LINQ)