Reputation: 1664
I have two lists of Generic types A
and B
:
public class A {
int type;
string params;
bool isActive;
}
public class B {
int type;
}
How could I map them into one list of type A
where B.type == A.type
(not A.type == B.type
!!) using linq?
Instances of class B
contain int
values that can be deleted or added whereas instances of class A
contain values from my db.
So for example:
A[0] = {1, "11", true}, A[1] = {2, "22", true}, A[2] = {3, "33", false}
and
B = {2, 3}
The desired result consists of A[1]
and A[2]
.
Upvotes: 3
Views: 7975
Reputation: 1062915
It sounds like what you mean is "filter the items from the first list by checking a property against a second list" - in which case, I would suggest:
build an index from the second list:
// create an index of the "type"s to look for
var index = new HashSet<int>(bList.Select(x => x.type));
use this to filter the data
// filter the primary list to values from the index
var matches = aList.FindAll(x => index.Contains(x.type));
This will very efficiently give you a list of just the A
data that has corresponding values in the bList
.
Here it is runnable:
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
public class A
{
public int type;
public string @params;
public bool isActive;
}
public class B
{
public int type;
}
static void Main()
{
var aList = new List<A>
{
new A { type = 1, @params = "11", isActive = true },
new A { type = 2, @params = "22", isActive = true },
new A { type = 3, @params = "33", isActive = false },
};
var bList = new List<B>
{
new B { type = 2 },
new B { type = 3 },
};
// create an index of the "type"s to look for
var index = new HashSet<int>(bList.Select(x => x.type));
// filter the primary list to values from the index
var matches = aList.FindAll(x => index.Contains(x.type));
foreach (var match in matches)
{
Console.WriteLine($"{match.type}, {match.@params}, {match.isActive}");
}
}
}
with output:
2, 22, True
3, 33, False
Upvotes: 3
Reputation: 30464
If you have two sequences, where both sequence have a value that should match, and you want to take zero or more properties form the first sequence and zero or more properties from the second sequence you use Enumerable.Join.
The syntax seems a bit difficult, but if used more often you get accustomed to it.
Suppose in your example you have a sequence of A objects and a sequence of B objects:
IEnumerable<A> myAobjects = ...
IEnumerable<B> myBobjects = ...
// do the join:
myAObjects.Join(myBobjects, // join the two sequences
myAobject => myAobject.type, // from the A sequence take property type
myBobject => myBobject.type, // from the B sequence also take property type
(myAobject, myBobject) => // whenever the values of these properties equal, take:
...);
The dots will be filed with what you want from the combination of a myAobject and a myBobject that have the same value for property type. Your question is simple: whenever a myAobject.type matches a myBobject.type, you want the complete myAObject. In that case the last part of the join is:
(myAobject, myBobject) => myAobject
If you wanted something else returned you would use something like:
(myAobject, myBobject) => new
{
MyParams = myAobject.Params,
MyOtherValue = myBObject.type,
}
Upvotes: 0
Reputation: 106
Is this what you are looking for !?
var result = arrayA.Where(a => arrayB.Select(b => b.type).Contains(a.type)).ToArray();
Upvotes: 1
Reputation: 460158
You want to join both lists, so find all A
which are in both lists?
var query = from a in aList
join b in bList
on a.type equals b.type
select a;
List<A> resultList = query.ToList();
Upvotes: 3