Home > OS >  Select all from one List, replace values that exist on another List
Select all from one List, replace values that exist on another List

Time:04-14

Few days ago I asked same question with SQL, but now it arises in C# code

Lets say we have this kind of class for holding different id/text pairs:

public class Text {
    public int id { get; set; }
    public string text { get; set; }
    ...
}

Now lets populate some data, ListA gets a lot of data:

List<Text> ListA = new List<Text>{
  new () {id = 1, text = "aaa1"},
  new () {id = 2, text = "aaa2"},
  new () {id = 3, text = "aaa3"},
  new () {id = 4, text = "aaa4"},
  new () {id = 5, text = "aaa5"},
  new () {id = 6, text = "aaa6"},
};

And ListB gets just a little bit of data:

List<Text> ListB = new List<Text>{
  new () {id = 4, text = "bbb4"},
  new () {id = 5, text = "bbb5"},
};

And now what we are looking:

var result = ... // Some Linq or Lambda magic goes here

// and if we do:
foreach(var item in result){
     Console.WriteLine(item.Id   " "   item.Text);
}

// Result will be:
1 : aaa1
2 : aaa2
3 : aaa3
4 : bbb4
5 : bbb5
6 : aaa6

CodePudding user response:

You can try looking for id within ListB:

var result = ListA
  .Select(a => ListB.FirstOrDefault(b => b.id == a.id) ?? a);

Here for each a within ListA we try to find corresponding by id (b.id == a.id) item within ListB. If no such item is found we just return ListA item: ?? item

In case of .Net 6 you can use overloaded .FirstOrDefault version (we can pass a as a default value):

var result = ListA
  .Select(a => ListB.FirstOrDefault(b => a.id == b.id, a));

CodePudding user response:

It might be more efficient to convert ListB to a Dictionary first: var dictB = ListB.ToDictionary(x=> x.id)

Then you can write

var result = ListA.Select(x => dictB.TryGetValue(x.id, out var b) ? b : x)

UPD Rewrote taking comment suggestions into account

  • Related