添加 IEnumerable到 IList<类型>其中 IList 不包含主键 - LAMBDA

发布于 2024-12-18 00:00:01 字数 557 浏览 2 评论 0原文

我有一个 IList;选定的价格。我还有一个稍后检索的 IEnumerable。我想添加从后者到前者的所有内容,其中前者不包含后者定义的主键。例如:

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

I have an IList<Price> SelectedPrices. I also have an IEnumerable<Price> that gets retrieved at a later date. I would like to add everything from the latter to the former where the former does NOT contain the primary key defined in the latter. So for instance:

IList<Price> contains Price.ID = 1, Price.ID = 2, and IEnumerable<Price> contains Price.ID = 2, Price.ID = 3, and Price.ID = 4. What's the easiest way to use a lambda to add those items so that I end up with the IList containing 4 unique Prices? I know I have to call ToList() on the IList to get access to the AddRange() method so that I can add multiple items at once, but how do I select only the items that DON'T exist in that list from the enumerable?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

十年不长 2024-12-25 00:00:01

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

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

最简单的选择就是循环并使用 contains:

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) 很大,这将防止例程出现二次方。

I know I have to call ToList() on the IList to get access to the AddRange() method

This is actually not safe. This will create a new List<T>, so you won't add the items to your original IList<T>. You'll need to add them one at a time.

The simplest option is just to loop and use a contains:

var itemsToAdd = enumerablePrices.Where(p => !SelectedPrices.Any(sel => sel.ID == p.ID));
foreach(var item in itemsToAdd)
{
    SelectedPrices.Add(item);
}

However, this is going to be quadratic in nature, so if the collections are very large, it may be slow. Depending on how large the collections are, it might actually be better to build a set of the IDs in advance:

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);
}

This will prevent the routine from going quadratic if your collection (SelectedPrices) is large.

捎一片雪花 2024-12-25 00:00:01

你可以尝试一下:

var newPrices = prices.Where(p => !SelectedPrices.Any(sp => sp.ID == p.ID));
foreach(var p in newPrices)
    SelectedPrices.Add(p);

我知道我必须在 IList 上调用 ToList() 才能访问 AddRange() 方法,以便我可以一次添加多个项目

ToList 将创建 List的新实例;,所以您将修改另一个列表,而不是原始列表...不,您需要一项一项地添加项目。

You can try that:

var newPrices = prices.Where(p => !SelectedPrices.Any(sp => sp.ID == p.ID));
foreach(var p in newPrices)
    SelectedPrices.Add(p);

I know I have to call ToList() on the IList to get access to the AddRange() method so that I can add multiple items at once

ToList will create a new instance of List<Price>, so you will be modifying another list, not the original one... No, you need to add the items one by one.

浅忆流年 2024-12-25 00:00:01

尝试 yourEnumerable.Where(x => !yourList.Any(y => y.ID == x.ID)) 作为问题的选择部分。

Try yourEnumerable.Where(x => !yourList.Any(y => y.ID == x.ID)) for the selection part of your question.

小耗子 2024-12-25 00:00:01

如果您想向现有列表添加新元素并以最高效的方式执行此操作,您可能应该以传统方式执行此操作。像这样:

    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);
        }
    }

If you want to add new elements to the existing list and do that in a most performant way you should probably do it in a conventional way. Like this:

    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);
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文