user1269810
user1269810

Reputation: 63

Assign values from one list to another using LINQ

Hello I have a little problem with assigning property values from one lists items to anothers. I know i could solve it "the old way" by iterating through both lists etc. but I am looking for more elegant solution using LINQ.

Let's start with the code ...

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

I would like to achieve the following:

In the end destinationList should contain:

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

Is there some kind of elegant (one line Lambda? ;) solution to this using LINQ ?

Any help will be greatly appreciated! Thanks!

Upvotes: 6

Views: 40459

Answers (5)

BrokenGlass
BrokenGlass

Reputation: 160902

I would just build up a dictionary and use that:

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

Upvotes: 9

Towhidul Islam Tuhin
Towhidul Islam Tuhin

Reputation: 1249

Hope this will your desired result. First join two list based on key(Id) and then set property value from sourceList.

        var result = destinationList.Join(sourceList, d => d.Id, s => s.Id, (d, s) =>
        {
            d.Name = s.Name;
            return d;
        }).ToList();

Upvotes: 8

amit_g
amit_g

Reputation: 31250

Barring the last requirement of "avoid creating new destinationList" this should work

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

To take care of "avoid creating new destinationList", below can be used, which is not any different than looping thru whole list, except that it probably is less verbose.

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

Upvotes: 4

Pablushka
Pablushka

Reputation: 103

I hope this will be useful for you. At the end, destinationList has the correct data, without creating any new list of any kind.

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

Upvotes: 0

jason
jason

Reputation: 241641

Frankly, this is the simplest:

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

You could do something ugly with Join but I wouldn't bother.

Upvotes: 0

Related Questions