Reputation: 2342
I have this scenario
class A
{
public string id { get; set; }
public string val1 { get; set; }
public string val2 { get; set; }
public string val3 { get; set; }
public string val4 { get; set; }
public string val5 { get; set; }
}
class B
{
public string id { get; set; }
public string val2 { get; set; }
public string val3 { get; set; }
}
List<A> lista = new List<A>(); //10 items
List<B> listb = new List<B>(); //400 items
I want to store in A
, the values of B
that match the id
field (val2
and val3
of B
into val2
and val3
of A
, by id
) , how can I do this?
Upvotes: 0
Views: 695
Reputation: 52250
You can use LINQ/Select to convert the B's into A's and add them with AddRange.
lista.AddRange
(
listb.Select
(
b => new A
{
id = b.id,
val2 = b.val2,
val3 = b.val3
}
)
);
Or, if you literally want to store both A's and B's in the same list, you can set up an inheritance relationship:
class B
{
public string id { get; set; }
public string val2 { get; set; }
public string val3 { get; set; }
}
class A : B
{
public string val1 { get; set; }
public string val4 { get; set; }
public string val5 { get; set; }
}
var listb = new List<B>();
Now your list can store both A and B, because A is a specialization of B. So you can do this:
listb.AddRange(lista);
If you want to keep the original objects in lista
and just want to update the matching properties, you should probably use a loop. It's possible to do it with LINQ if you really want, but it's really not "meant" for updating things in place.
It does make things a little easier to store your As in a dictionary, since you get the lookup ability. A dictionary uses a hash table internally so you will also get better performance than a scan. Because the dictionary only contains references, the objects in the original list will get updated too.
var dictionarya = lista.ToDictionary
(
item => item.id,
item => item
);
foreach (var b in listb)
{
A a;
if (dictionarya.TryGetValue(b.id, out a))
{
a.val2 = b.val2;
a.val3 = b.val3;
}
}
Upvotes: 1
Reputation: 56433
Seems like a good job for the Join
clause:
var result = lista.Join(listb,
a => a.id,
b => b.id,
(a, b) =>
new A { id = a.id, val2 = b.val2, val3 = b.val3 });
This will accomplish your description of "I want to store in A
, the values of B
that match the id
field".
if instead, you want to accumulate the result from the Join
clause to lista
, then you can utilise the AddRange
method:
lista.AddRange(result);
Upvotes: 0
Reputation: 9704
The following LINQ query should get you there:
lista.AddRange(from b in listb
let a = new A { id = b.id, val2 = b.val2, val3 = b.val3}
where lista.Any(x => x.id == a.id)
select a);
This will select a list of all B that share an ID with a value in lista, then add the result to lista.
Upvotes: 1