Добавление IEnumerable <Type>в IList <Type>, где IList не содержит первичный ключ - LAMBDA - PullRequest
0 голосов
/ 22 ноября 2011

У меня есть IList<Price> SelectedPrices.У меня также есть IEnumerable<Price>, который будет получен позже.Я хотел бы добавить все от последнего к первому, где первый НЕ содержит первичный ключ, определенный во втором.Например,

IList<Price> содержит Price.ID = 1, Price.ID = 2, а IEnumerable<Price> содержит Price.ID = 2, Price.ID = 3 и Price.ID = 4.Какой самый простой способ использовать лямбду для добавления этих предметов, чтобы я получил IList, содержащий 4 уникальных цены?Я знаю, что должен вызвать ToList() на IList, чтобы получить доступ к методу AddRange(), чтобы я мог добавить несколько элементов одновременно, но как выбрать только те элементы, которые НЕ существуют в этом списке, изперечислимый?

Ответы [ 4 ]

4 голосов
/ 22 ноября 2011

Я знаю, что должен вызвать ToList () в IList, чтобы получить доступ к методу AddRange ()

Это на самом деле небезопасно.Это создаст новый List<T>, поэтому вы не добавите элементы в ваш исходный IList<T>.Вам нужно будет добавлять их по одному за раз.

Самый простой вариант - просто зацикливание и использование содержимого:

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

Однако это будет квадратичный характер,так что если коллекции очень большие, это может быть медленно.В зависимости от того, насколько велики коллекции, на самом деле может быть лучше заранее создать набор идентификаторов:

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) велика.

1 голос
/ 22 ноября 2011

Если вы хотите добавить новые элементы в существующий список и сделать это наиболее эффективным способом, вам, вероятно, следует сделать это обычным способом. Как это:

    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);
        }
    }
1 голос
/ 22 ноября 2011

Вы можете попробовать это:

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

Я знаю, что мне нужно вызвать ToList () для IList, чтобы получить доступ к методу AddRange (), чтобы я мог добавить несколькоэлементы сразу

ToList создаст новый экземпляр List<Price>, поэтому вы будете изменять другой список, а не исходный ... Нет, вам нужно добавить элементы по одномуодин.

1 голос
/ 22 ноября 2011

Попробуйте yourEnumerable.Where(x => !yourList.Any(y => y.ID == x.ID)) для выбора части вашего вопроса.

...