合并两个对象列表,但根据不同的值删除重复项

时间:2019-03-18 15:15:26

标签: c# list linq iqueryable

我有两个对象列表:

List1 = [ {id: 1, parentId: null}, {id:2, parentId: null} ]
List2 = [ {id: 3, parentId: 1} ]

我想返回这两个的联合列表,但不包含ID为parentId的List2中的List1。在上面的示例中,我的结果将是:

UnionList = [ {id:3, parentId: 1}, {id:2, parentId: null} ]

另一件事:两个列表最初是两个IQueryable;我简单地执行一个ToList()以将它们作为列表。

如何使用列表(如果不需要ToList(),则可以使用Iqueryables)获得正确的结果?

谢谢!

3 个答案:

答案 0 :(得分:2)

我想我得到了您想要的-您不希望两次不显示任何ID。因此,如果在“父母”字段中使用了一些“父母”,您是否不希望结果中额外包含它?

在这种情况下,您可以这样做:

var result = List1.Where(x => !List2.Any(l2 => l2.parentId == x.id)).Union(List2);//.ToList();

Where部分排除了所有在List2中用作父项的项目。然后,通过Union(排除重复项)合并List2。 ToList()可能是可选的,具体取决于下一步要执行的操作。

编辑:将表格Concat更改为Union。

答案 1 :(得分:0)

您可以尝试在迭代List1时从List2中找到第一个匹配的ParentId,并根据是否找到它进行添加:

var UnionList = new List<Item>();
foreach (var item in List1)
{
    var match = List2.FirstOrDefault(x => x.ParentId == item.Id);
    resultList.Add(match ?? item);
}

或仅使用LINQ:

var UnionList = new List<Item>(List1.Select(item => List2.FirstOrDefault(x => x.ParentId == item.Id) ?? item));

答案 2 :(得分:0)

您可以使用System.Linq扩展方法Union(以获取两个列表的并集)以及WhereAll来过滤掉不需要的项目包含在第一个列表中:

var result = list2.Union(list1.Where(l1 => list2.All(l2 => l2.ParentId != l1.Id)));

但是请注意,Union将使用该类的Equals方法来确定两个项目是否匹配(默认情况下是引用比较),因此您需要覆盖{{1} }和Equals以便删除重复项(您将定义重复项,在这种情况下,我想应该在两个项目的GetHashCode属性匹配的地方进行定义,但也许您会包含{{ 1}})。

例如:

Id

然后一个示例用法是:

ParentId