如何高效地合并两个集合?(相关于IT技术)

4

我有以下算法来找到两个集合的并集。

IEnumerable<IGroup> labelGroups = _agents.Where(x => settings.LabelIds.Contains(x.Id));
IEnumerable<Guid>labelAgentIds = labelGroups.SelectMany(x => x.AgentIds);

settings.AgentIds = new Collection<Guid>(labelAgentIds.Union(settings.AgentIds).ToList());

或者

IEnumerable<IGroup> labelGroups = _agents.Where(x => settings.LabelIds.Contains(x.Id));
agentIds = labelGroups.Aggregate(agentIds, (current, label) => current.Union(label.AgentIds));

我应该使用哪个算法?帮我比较一下这些算法(速度和内存)。


我认为你必须使用第二个算法。 - user3644716
5
请使用Stopwatch类进行检查,或者使用性能分析方法。 - Fabjan
1
你想避免重复项吗?如果是的话,你可以使用 HashSet<T> 和方法 UnionWith。正如 @Fabjan 所说,使用 Stopwatch 可以很好地检查性能。 - Felipe Oriani
@FelipeOriani 是的,我想要。 - Anatoly
也许这篇文章可以帮到你:http://alicebobandmallory.com/articles/2012/10/18/merge-collections-without-duplicates-in-c - Felipe Oriani
1
这是 http://stackoverflow.com/questions/32779641/what-is-the-most-efficient-way-to-find-union-of-two-collections 的重复吗? - Jim Mischel
1个回答

5

为了获得最佳性能,请将settings.LabelIds放入HashSet中。

var labelIds = new HashSet<int>(settings.LabelIds);

然后使用哈希集合进行快速查找,时间复杂度为O(1)。

var labelAgentIds = _agents.Where(x => labelIds.Contains(x.Id)).SelectMany(x => x.AgentIds);

如果您知道labelAgentIdssettings.AgentIds的ID永远不相同,您可以使用Concat。否则,请使用Union以确保没有重复项。
settings.AgentIds = new Collection<Guid>(labelAgentIds.Union(settings.AgentIds).ToList())

使用“聚合”方法会更慢。

请问您能否解释一下为什么会更慢? - Anatoly
如果你运行Aggregate,你必须为列表中的每个项目执行union。例如,如果您想连接两个字符串,您不会循环第二个字符串并逐个附加字符。但更重要的是,使用union可以更清晰地显示代码的意图。这使得未来的维护者更容易理解和维护代码。 - Magnus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接