Назначить значения из одного списка в другой с помощью LINQ - PullRequest
6 голосов
/ 14 марта 2012

Здравствуйте. У меня небольшая проблема с назначением значений свойств из одного списка элементов другим. Я знаю, что могу решить это «по-старому», перебирая оба списка и т. Д., Но я ищу более элегантное решение с использованием LINQ.

Давайте начнем с кода ...

class SourceType
{
    public int Id;
    public string Name;
    // other properties
}

class DestinationType
{
    public int Id;
    public string Name;
    // other properties
}

List<SourceType> sourceList = new List<SourceType>();
sourceList.Add(new SourceType { Id = 1, Name = "1111" });
sourceList.Add(new SourceType { Id = 2, Name = "2222" });
sourceList.Add(new SourceType { Id = 3, Name = "3333" });
sourceList.Add(new SourceType { Id = 5, Name = "5555" });

List<DestinationType> destinationList = new List<DestinationType>();
destinationList.Add(new DestinationType { Id = 1, Name = null });
destinationList.Add(new DestinationType { Id = 2, Name = null });
destinationList.Add(new DestinationType { Id = 3, Name = null });
destinationList.Add(new DestinationType { Id = 4, Name = null });

Я бы хотел добиться следующего:

  • destinationList должен быть заполнен Именами соответствующих записей (по Id) в sourceList
  • destinationList не должен содержать записи, которые не присутствуют в обоих списках одновременно (например, Id: 4,5 следует исключить) - что-то вроде внутреннего соединения
  • Я бы хотел избежать создания нового destinationList с обновленными записями, поскольку оба списка уже существуют и очень велики, так что нет "конвертировать" или "выбрать новый".

В конце destinationList должен содержать:

1 "1111"
2 "2222"
3 "3333"

Есть ли какое-нибудь элегантное (однострочное лямбда?) Решение для этого с помощью LINQ?

Любая помощь будет принята с благодарностью! Спасибо!

Ответы [ 5 ]

8 голосов
/ 14 марта 2012

Я бы просто создал словарь и использовал его:

Dictionary<int, string> map = sourceList.ToDictionary(x => x.Id, x => x.Name);

foreach (var item in destinationList)
    if (map.ContainsKey(item.Id))
        item.Name = map[item.Id];

destinationList.RemoveAll(x=> x.Name == null);
6 голосов
/ 20 октября 2015

Надеюсь, что это будет ваш желаемый результат. Сначала объедините два списка на основе ключа (Id), а затем установите значение свойства из sourceList.

        var result = destinationList.Join(sourceList, d => d.Id, s => s.Id, (d, s) =>
        {
            d.Name = s.Name;
            return d;
        }).ToList();
4 голосов
/ 14 марта 2012

Запрет последнего требования «избегать создания нового destinationList» это должно работать

var newList = destinationList.Join(sourceList, d => d.Id, s => s.Id, (d, s) => s);

Чтобы позаботиться о «избегать создания нового destinationList», можно использовать ниже, что ничем не отличается от цикла черезвесь список, за исключением того, что он, вероятно, менее многословен.

destinationList.ForEach(d => {
                               var si = sourceList
                                           .Where(s => s.Id == d.Id)
                                           .FirstOrDefault();
                               d.Name = si != null ? si.Name : "";
                             });
destinationList.RemoveAll(d => string.IsNullOrEmpty(d.Name));
0 голосов
/ 14 марта 2012

Надеюсь, это будет полезно для вас.В конце, destinationList содержит правильные данные, без создания какого-либо нового списка любого типа.

        destinationList.ForEach(x =>
        {
            SourceType newSource = sourceList.Find(s=>s.Id == x.Id);
            if (newSource == null)
            {
                destinationList.Remove(destinationList.Find(d => d.Id == x.Id));
            }
            else
            {
                x.Name = newSource.Name;
            }
        });
0 голосов
/ 14 марта 2012

Честно говоря, это самое простое:

var dictionary = sourceList.ToDictionary(x => x.Id, x => x.Name);
foreach(var item in desitnationList) {
    if(dictionary.ContainsKey(item.Id)) {
        item.Name = dictionary[item.Id];
    }
}
destinationList = destinationList.Where(x => x.Name != null).ToList();

Вы могли бы сделать что-то ужасное с Join, но я бы не стал беспокоиться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...