简体   繁体   English

使用LINQ在两个列表之间进行“左XOR”

[英]“Left XOR” between two lists with LINQ

I have to collections: 我要收藏:

IEnumerable<lineResult> diplayedBondsList

and

List<string> pIsinList

lineResult is a very simple class defined as: lineResult是一个非常简单的类,定义为:

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

I am trying to create a new List with the string that are in pIsinList, but only if they are not already in the field isin of a "lineResult" element of diplayedBondsList. 我试图用pIsinList中的字符串创建一个新List,但前提是它们不在diplayedBondsList的“ lineResult”元素字段中。 Kind of a "left XOR" (left because only one of the two lists elements would be added without a correspondance in the other table). 一种“左XOR”(左,因为仅会添加两个列表元素之一,而在另一个表中没有对应关系)。

I am trying to not use too many loop because my lists have a very large amount of data, and I think that would slow down the program. 我试图不使用太多循环,因为我的列表中包含大量数据,并且我认为这样做会使程序变慢。

I have written this, but it does not seem to work, newBondLines always being empty: 我已经写了这个,但是它似乎不起作用,newBondLines总是空的:

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

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

In addition, I do use a loop, and maybe I could avoid it with a nice LINQ statement. 另外,我确实使用了循环,也许我可以通过一个不错的LINQ语句来避免它。

How could I 1) make this "left XOR" work and 2) improve its speed? 我如何1)使此“左XOR”工作和2)提高其速度?

Using the Enumerable.Except : 使用Enumerable.Except

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

Note that this command will do implicitly a Distinct() on pIsinList (something that isn't explained in the MSDN, but that if you look at the source is quite clear), so if you had new[] { "A", "A" } in pIsinList , the end result will be a single "A" . 请注意,此命令将在pIsinList上隐式执行Distinct() (MSDN中未对此进行解释,但是如果您看一下源代码,则很清楚),因此,如果您有new[] { "A", "A" } pIsinList new[] { "A", "A" } ,最终结果将是单个"A"

You can do the Except "manually" to solve this "problem" (if it is a problem): 您可以“手动”执行“ Except ”以解决此“问题”(如果有问题):

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

You can use Contains from the second list: 您可以从第二个列表中使用“ Contains ”:

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

I don't think the speed can be improved, because whatever the method, you will always have to compare all items in one list to all items in the other. 我认为速度无法提高,因为无论采用哪种方法,您都将不得不将一个列表中的所有项目与另一个列表中的所有项目进行比较。 Even if you remove the loop, Linq will have to do one (or several) under the hood. 即使您删除了循环,Linq也将不得不在后台执行一项(或多项)。

There is an extension for XOR, left XOR or right XOR between two lists : https://stackoverflow.com/a/45480272/2546739 两个列表之间有XOR扩展,左XOR或右XOR: https : //stackoverflow.com/a/45480272/2546739

(It is not with LINQ) (不是LINQ)

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

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