"Left XOR" 使用 LINQ 在两个列表之间

"Left XOR" between two lists with LINQ

我必须 collections:

IEnumerable<lineResult> diplayedBondsList

List<string> pIsinList

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

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

我正在尝试使用 pIsinList 中的字符串创建一个新列表,但前提是它们不在 diplayedBondsList 的 "lineResult" 元素的字段 isin 中。有点像 "left XOR"(左边是因为只有两个列表元素之一会被添加而另一个 table 中没有对应关系)。

我尽量不使用太多循环,因为我的列表有大量数据,我认为这会减慢程序速度。

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

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

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

此外,我确实使用了一个循环,也许我可以使用一个不错的 LINQ 语句来避免它。

我怎样才能 1) 让这个 "left XOR" 工作并 2) 提高它的速度?

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

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

我不认为可以提高速度,因为无论使用哪种方法,您总是必须将一个列表中的所有项目与另一个列表中的所有项目进行比较。即使您删除循环,Linq 也必须在后台执行一个(或多个)操作。

使用 Enumerable.Except:

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

请注意,此命令将在 pIsinList 上隐式执行 Distinct()(MSDN 中未解释的内容,但如果您查看 source 就很清楚了),所以如果你在 pIsinList 中有 new[] { "A", "A" },最终结果将是一个 "A".

你可以通过Except "manually"来解决"problem"(如果是问题的话):

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

两个列表之间有异或扩展,左异或或右异或:

(不支持 LINQ)