Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将IEnumerable添加到IList中,其中IList不包含主键-LAMBDA_C#_.net_Lambda_Ienumerable_Ilist - Fatal编程技术网

C# 将IEnumerable添加到IList中,其中IList不包含主键-LAMBDA

C# 将IEnumerable添加到IList中,其中IList不包含主键-LAMBDA,c#,.net,lambda,ienumerable,ilist,C#,.net,Lambda,Ienumerable,Ilist,我有一个IList SelectedPrices。我还有一个IEnumerable,可以在以后检索。我想添加从后者到前者的所有内容,前者不包含后者中定义的主键。例如: IList包含Price.ID=1、Price.ID=2,IEnumerable包含Price.ID=2、Price.ID=3和Price.ID=4。使用lambda添加这些项目的最简单方法是什么,这样我就可以得到包含4个唯一价格的IList?我知道我必须在IList上调用ToList才能访问AddRange方法,这样我就可以一次

我有一个IList SelectedPrices。我还有一个IEnumerable,可以在以后检索。我想添加从后者到前者的所有内容,前者不包含后者中定义的主键。例如:

IList包含Price.ID=1、Price.ID=2,IEnumerable包含Price.ID=2、Price.ID=3和Price.ID=4。使用lambda添加这些项目的最简单方法是什么,这样我就可以得到包含4个唯一价格的IList?我知道我必须在IList上调用ToList才能访问AddRange方法,这样我就可以一次添加多个项,但是如何从枚举表中仅选择该列表中不存在的项呢

我知道我必须在IList上调用ToList才能访问AddRange方法

这实际上是不安全的。这将创建一个新列表,因此您不会将项目添加到原始IList。您需要一次添加一个

最简单的选项是循环并使用包含:

var itemsToAdd = enumerablePrices.Where(p => !SelectedPrices.Any(sel => sel.ID == p.ID));
foreach(var item in itemsToAdd)
{
    SelectedPrices.Add(item);
}
然而,这在本质上是二次的,所以如果集合非常大,它可能会很慢。根据集合的大小,实际上最好提前构建一组ID:

var existing = new HashSet<int>(SelectedPrices.Select(p => p.ID));
var itemsToAdd = enumerablePrices.Where(p => !existing.Contains(p.ID));
foreach(var item in itemsToAdd)
{
    SelectedPrices.Add(item);
}
如果您的集合SelectedPrices很大,这将防止例程变为二次型。

请尝试您的Enumerable。其中x=>!yourList.Anyy=>y.ID==x.ID,用于问题的选择部分。

您可以尝试:

var newPrices = prices.Where(p => !SelectedPrices.Any(sp => sp.ID == p.ID));
foreach(var p in newPrices)
    SelectedPrices.Add(p);
我知道我必须在IList上调用ToList才能访问AddRange方法,以便一次添加多个项


ToList将创建列表的新实例,因此您将修改另一个列表,而不是原始列表。。。不,您需要逐个添加项目。

如果您想向现有列表中添加新元素,并以最有效的方式进行添加,您可能应该以常规方式进行添加。像这样:

    IList<Price> selectedPrices = ...;
    IEnumerable<Price> additionalPrices = ...;

    IDictionary<int, Price> pricesById = new Dictionary<int, Price>();

    foreach (var price in selectedPrices) 
    { 
        pricesById.Add(price.Id, price); 
    }


    foreach (var price in additionalPrices)
    {
        if (!pricesById.ContainsKey(price.Id))
        {
            selectedPrices.Add(price);
        }
    }

请注意,要使尖括号正确显示,必须将其格式化为代码,可以是反勾号,也可以是四个空格的缩进。编辑器中的{}按钮将对所选文本执行正确的操作,将其格式化为codeAh,这是有意义的。我本想离开foreach,但这太完美了。谢谢,我明白了。所以Where->Any选择器将映射两个列表中的所有ID,从而强制使用二次型?不管怎样,第二段代码似乎同样可读。@user623647是-对于n个SelectedPrice实例,.Any将处于启用状态。这使得可枚举中的N个元素和列表中的m个元素处于*m。第二个选项变为线性,但初始设置哈希集的开销更大。如果集合总是很小,我只会使用第一个-但是如果选择的价格可能很大,第二个将阻止你去二次。