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

问题描述 投票:0回答:3

我有两个对象列表:

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

我想返回这两个的联合列表,但没有List2中的List1,其id为parentId。以上示例中的结果将是:

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

还有一件事:两个列表最初是两个IQueryables;我简单地做一个ToList()将它们作为列表。

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

提前致谢!

c# list linq iqueryable
3个回答
2
投票

我想我得到了你想要的东西 - 你想不再出现任何两次id。因此,如果在“父”字段中使用某些“父”,您不希望在结果中添加额外的吗?

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

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

Where-part排除了在List2中用作父项的所有项目。与Union(不包括重复)一起,它合并了List2。 ToList()可能是可选的,具体取决于您接下来要做的事情。

编辑:将Concat从Concat更改为Union。


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));

0
投票

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

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

但是请注意,Union将使用类的Equals方法来确定两个项是否匹配(默认情况下是参考比较),因此您需要覆盖EqualsGetHashCode以删除重复项(其中将重复定义)由你,在这种情况下,我想将定义两个项目的Id属性匹配,但也许你会包括ParentId)。

例如:

public class Item
{
    public int Id { get; set; }
    public int? ParentId { get; set; }

    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }

    public override bool Equals(object obj)
    {
        return Id == (obj as Item)?.Id;
    }
}

然后一个示例用法是:

public class Program
{
    private static void Main(string[] args)
    {
        var list1 = new List<Item>
        {
            new Item {Id = 1, ParentId = null},
            new Item {Id = 2, ParentId = null},
            new Item {Id = 3, ParentId = 1}
        };

        var list2 = new List<Item>
        {
            new Item {Id = 3, ParentId = 1}
        };

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

        GetKeyFromUser("\nDone! Press any key to exit...");
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.