如何在 C# 中合并两个列表并合并其内部列表而不重复
How to Merge two lists and Merge it's inner lists without duplication in C#
我正在尝试使用 LINQ 合并两个通用列表-
List<LinkedTable> FirstLink
List<LinkedTable> SecondLink
如下图Class所示,我的通用列表本身就有一个通用列表。
public class LinkedTable
{
public string TableId { get; set; }
public string TableName { get; set; }
public List<Link> innerLinks { get; set; }
}
public class Link
{
public Boolean linkFlag;
public string Descriptor { get; set; }
public string RecordId { get; set; }
}
当我合并两个列表时,新列表不包含 FirstLink 和 SecondLink 的 "innerLinks" 记录。
我试过以下代码:
FirstLink = FirstLink.Concat(SecondLink)
.GroupBy(e1 => e1.TableId)
.Select(e2 => e2.FirstOrDefault())
.ToList();
现在,FirstLink 将获得按 "TableId " 分组的所有表格,但缺少 SecondLink 中的一些 "innerLinks"。
我需要新合并列表中 FirstLink 和 SecondLink 的 "innerLinks" 列表,不重复。
示例:
FirstLink[0].innerLinks[0]
.innerLinks[1]
.innerLinks[2]
SecondLink[0].innerLinks[1]
.innerLinks[2]
.innerLinks[3]
合并Link应该是:
FirstLink[0].innerLinks[0]
.innerLinks[1]
.innerLinks[2]
.innerLinks[3]
这里有一个选项:
首先,您必须提供一种方法来告诉 Linq 什么使 Link 等于另一个。您可以通过以下任一方法执行此操作:
- 创建一个 class 工具
IEqualityComparer<Link>
并将其实例作为参数传递给 Distinct
;
- 在 Link class
上实施 IEquatable<Link>
并覆盖 GetHashCode
- 覆盖
Equals
和 GetHashCode
Link class。
假设 RecordId 是 Link 对象的唯一标识符,这就是实现 IEquatable<Link>
:
的方法
public class Link : IEquatable<Link>
{
public Boolean linkFlag;
public string Descriptor { get; set; }
public string RecordId { get; set; }
public bool Equals(Link other)
{
//Adjust for a suiting identifier and do all the sanity checks, if needed.
return this.RecordId == other.RecordId;
}
public override int GetHashCode()
{
//You can also use another GetHash approach that suits you better.
return this.RecordId.GetHashCode();
}
}
然后,您可以 Concat
两个列表,然后按 TableId 和 TableName 分组。最后,您在分组的 LinkedTable 的内部 Link 上使用 SelectMany
到 select 该组中包含的所有 Link。 Distinct
将必须采用 IEqualityComparer
的实例,以防您选择那样做。
var merged =
from item in FirstLink.Concat(SecondLink)
group item by new { Id = item.TableId, Name = item.TableName } into tbGp
select new LinkedTable
{
TableId = tbGp.Key.Id,
TableName = tbGp.Key.Name,
innerLinks = tbGp.SelectMany(p => p.innerLinks).Distinct().ToList()
};
Distinct
和 IEquatable<T>
解释 on MSDN
覆盖 Equals
和 GetHashCode
on MSDN
您的查询不起作用,因为当您分组时,您正在获取组的第一个元素和它的 Link
个对象列表。
要实现您的结果,您应该尝试以下代码:
var FirstLink = FirstLink
.Concat(SecondLink)
.GroupBy(e1 => e1.TableId)
// Don't take the first item, but create a new one with the items you need
.Select(e2 => new LinkedTable
{
TableId = e2.Key,
TableName = e2.First().TableName,
innerLinks = e2.SelectMany(x => x.innerLinks).ToList()
})
.ToList();
我正在尝试使用 LINQ 合并两个通用列表-
List<LinkedTable> FirstLink
List<LinkedTable> SecondLink
如下图Class所示,我的通用列表本身就有一个通用列表。
public class LinkedTable
{
public string TableId { get; set; }
public string TableName { get; set; }
public List<Link> innerLinks { get; set; }
}
public class Link
{
public Boolean linkFlag;
public string Descriptor { get; set; }
public string RecordId { get; set; }
}
当我合并两个列表时,新列表不包含 FirstLink 和 SecondLink 的 "innerLinks" 记录。 我试过以下代码:
FirstLink = FirstLink.Concat(SecondLink)
.GroupBy(e1 => e1.TableId)
.Select(e2 => e2.FirstOrDefault())
.ToList();
现在,FirstLink 将获得按 "TableId " 分组的所有表格,但缺少 SecondLink 中的一些 "innerLinks"。
我需要新合并列表中 FirstLink 和 SecondLink 的 "innerLinks" 列表,不重复。
示例:
FirstLink[0].innerLinks[0]
.innerLinks[1]
.innerLinks[2]
SecondLink[0].innerLinks[1]
.innerLinks[2]
.innerLinks[3]
合并Link应该是:
FirstLink[0].innerLinks[0]
.innerLinks[1]
.innerLinks[2]
.innerLinks[3]
这里有一个选项:
首先,您必须提供一种方法来告诉 Linq 什么使 Link 等于另一个。您可以通过以下任一方法执行此操作:
- 创建一个 class 工具
IEqualityComparer<Link>
并将其实例作为参数传递给Distinct
; - 在 Link class 上实施
- 覆盖
Equals
和GetHashCode
Link class。
IEquatable<Link>
并覆盖 GetHashCode
假设 RecordId 是 Link 对象的唯一标识符,这就是实现 IEquatable<Link>
:
public class Link : IEquatable<Link>
{
public Boolean linkFlag;
public string Descriptor { get; set; }
public string RecordId { get; set; }
public bool Equals(Link other)
{
//Adjust for a suiting identifier and do all the sanity checks, if needed.
return this.RecordId == other.RecordId;
}
public override int GetHashCode()
{
//You can also use another GetHash approach that suits you better.
return this.RecordId.GetHashCode();
}
}
然后,您可以 Concat
两个列表,然后按 TableId 和 TableName 分组。最后,您在分组的 LinkedTable 的内部 Link 上使用 SelectMany
到 select 该组中包含的所有 Link。 Distinct
将必须采用 IEqualityComparer
的实例,以防您选择那样做。
var merged =
from item in FirstLink.Concat(SecondLink)
group item by new { Id = item.TableId, Name = item.TableName } into tbGp
select new LinkedTable
{
TableId = tbGp.Key.Id,
TableName = tbGp.Key.Name,
innerLinks = tbGp.SelectMany(p => p.innerLinks).Distinct().ToList()
};
Distinct
和 IEquatable<T>
解释 on MSDN
覆盖 Equals
和 GetHashCode
on MSDN
您的查询不起作用,因为当您分组时,您正在获取组的第一个元素和它的 Link
个对象列表。
要实现您的结果,您应该尝试以下代码:
var FirstLink = FirstLink
.Concat(SecondLink)
.GroupBy(e1 => e1.TableId)
// Don't take the first item, but create a new one with the items you need
.Select(e2 => new LinkedTable
{
TableId = e2.Key,
TableName = e2.First().TableName,
innerLinks = e2.SelectMany(x => x.innerLinks).ToList()
})
.ToList();