gpt4 book ai didi

c# - 从 HashSet 替换并合并 "Duplicates"

转载 作者:行者123 更新时间:2023-12-02 22:21:25 24 4
gpt4 key购买 nike

我有一个 HashSet<T> C# 4.0 中的分层对象。主键是一个 int,但偶尔会有重复的辅助键。我想将条目与重复的辅助键合并。在此示例中,辅助键是名称:

struct Element
{
int ID;
string Name;
List<int> Children;
List<int> Parents;

public override int GetHashCode()
{
return ID;
}
}

HashSet<Element> elements = new HashSet<Element>();

// Example Elements
elements.Add(1, "Apple", Children = {10, 11, 12}, Parents = {13,14,15});
elements.Add(2, "Banana", Children = {20, 21, 22}, Parents = {23,24,25});
elements.Add(3, "Apple", Children = {30, 31, 32}, Parents = {33,34,35});
elements.Add(4, "Food", Children = {1, 2, 3}, Parents = {});

目标是删除第 3 个条目 {3, "Apple",...} 然后更新并合并其他剩余元素中的 Parent 和 Children 引用;最终结果应该是这样的:

{ 1, "Apple", Children = { 10, 11, 12, 30, 31, 32 }, Parents = { 13,14,15, 33, 34, 35 }}
{ 2, "Banana", Children = { 20, 21, 22 }, Parents = { 23,24,25 }}
{ 4, "Food", Children = {1, 2}, Parents = {} }

这是我目前所掌握的,但我想不出更新 HashSet 的最佳方法。我从复制 HashSet 开始,这样我就可以在迭代时进行删除。首先,我找到重复项。如果有重复项,我想更新并将它们从副本中删除。那就是我卡住的地方。更新重复项后,我想删除它们,并防止使用跳过列表再次处理它们:

var copy = new HashSet<Element>(Elements);
HashSet<int> skip = new HashSet<int>();
foreach (var e in Elements)
{
if (!skip.Contains(e.ID)
{
var duplicates = Elements.Where(x => e.Name == x.Name && e.ID != x.ID);
if (duplicates.Any())
{
foreach (var d in duplicates)
{
// Iterate copy and update Parent and Children references
// How do I do this part?
}

// Remove the duplicates from the copied list
copy.RemoveWhere(x => duplicates.Select(x => x.ID)
.Contains(x.ID));

// Don't process the duplicates again
skip.UnionWith(duplicates);
}
}
}
return copy;

我卡在这一步了。另外,有没有一种巧妙的方法可以使用 Linq 来做到这一点?

更新: 列表已经是这样了,我无法控制初始内容。我想我可以创建一个新的包装器,它具有更好的 Add 方法来防止重复。

最佳答案

尝试添加这个单一字段元素。

struct Element
{
int ID;
string Name;
List<int> Children;
List<int> Parents;
Bool duplicate;
}

HashSet<Element> Elements = new HashSet();

// Example Elements
Elements.Add(1, "Apple", Children = {10, 11, 12}, Parents = {13,14,15}, duplicate = false);
Elements.Add(2, "Banana", Children = {20, 21, 22}, Parents = {23,24,25}, duplicate = false);
Elements.Add(3, "Apple", Children = {30, 31, 32}, Parents = {33,34,35}, duplicate = false);
Elements.Add(4, "Food", Children = {1, 2, 3}, Parents = {}, duplicate = false);

当您迭代副本时,将“重复”标记为真。或者添加一个“已删除”元素,这样您就不会重新处理。管他呢。关键是,再添加一个元素。您始终可以复制元素并在添加时创建新元素。

要早点添加到新浪的评论中,你可以有这样一个 key :

class ElementKey {
int ID;
string Name;
}

class Element {
ElementKey Key;
List<int> Children;
List<int> Parents;
ProcessFlagSet flags;
}

class ProcessFlagSet {
bool Processed;
bool Duplicate;
}

Dictionary<ElementKey,Element> ...

然后您可以稍后从 ProcessFlagSet 中删除所有元素,以满足轻松的重构需求。如果您不需要它们,它们会破坏编译,直到它们被删除。

最后,我想推荐在这里创建您自己的 Add 方法。我希望你考虑传入要添加的元素,然后在添加时检查键是否存在。这为您节省了一步。

关于c# - 从 HashSet 替换并合并 "Duplicates",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13676075/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com