Пересекают два списка с разными объектами
У меня есть список ObjA и ObjB следующим образом:
List<ObjA> List1;
List<ObjB> List2;
Оба ObjA и ObjB имеют общее поле, которое является User, и я хочу пересечь их на основе User.Id.
class ObjA
{
User user;
.... other properties
}
class ObjB
{
User user;
.... other properties
}
class User
{
int Id;
.... other props
}
Как я могу пересечь эти два списка в User.Id с помощью linq?
В результате я хочу только список пользователей.
Ответы
Ответ 1
Общая идея
var commonUsers = list1.Select(a => a.User).Intersect(list2.Select(b => b.User));
Однако сам по себе это предполагает, что User
реализует IEquatable<User>
, что, похоже, не имеет места здесь. Поэтому вам нужно либо добавить эту реализацию, либо использовать перегрузку Intersect
, которая принимает пользовательский IEqualityComparer<User>
.
Ответ 2
без необходимости IEqualityComparer или IEquatable (что было бы лучше в любом случае)
var commonUsers = list1
.Select(l1 => l1.User)
.Where(u => list1
.Select(l => l.User.Id)
.Intersect(list2
.Select(l2 => l2.Id))
.Contains(u.Id));
или
var commonUsers = list1.Select(l1 => l1.User)
.Where(u=> list2.Select(l2 => l2.User.Id)
.Contains(u.Id));
Ответ 3
Стандартный способ - использовать объект IEqualityComparer
. По умолчанию используется стандартное сравнение равенства. Создайте класс, который реализует интерфейс IEqualityComparer
и выполняет сравнение, которое вы хотите. Затем вы можете вызвать перегрузку IEnumerable.Intersect
, которая принимает экземпляр вашего класса сравнения
Ответ 4
1. Посмотрите на этот простой код
var result = (from objA in objAList
join objB in objBList on objA.user.Id equals objB.user.Id
select objA/*or objB*/).ToList();
2.полный код
class QueryJoin
{
static void Main(string[] args)
{
//create users
User user1 = new User { Id = 1, Name = "anuo1" };
User user2 = new User { Id = 2, Name = "anuo2" };
User user3 = new User { Id = 3, Name = "anuo3" };
User user4 = new User { Id = 4, Name = "anuo4" };
User user5 = new User { Id = 5, Name = "anuo5" };
//create objAList
List<ObjA> objAList = new List<ObjA>();
objAList.Add(new ObjA { user = user1 });
objAList.Add(new ObjA { user = user2 });
objAList.Add(new ObjA { user = user3 });
//create objBList
List<ObjB> objBList = new List<ObjB>();
objBList.Add(new ObjB { user = user3 });
objBList.Add(new ObjB { user = user4 });
objBList.Add(new ObjB { user = user5 });
//intersect
var result = (from objA in objAList
join objB in objBList on objA.user.Id equals objB.user.Id
select objA/*or objB*/).ToList();
}
}
class ObjA
{
public User user { get; set; }
}
class ObjB
{
public User user { get; set; }
}
class User
{
public int Id { get; set; }
public string Name { get; set; }
}