c# - 创建集合的差异
问题描述
我想在 C# (LINQ) 中创建两个集合的“合并差异”。假设,以下 2 个字符串集合,并且输入集合已排序:
a - a
b - c
e - d
预期的输出应该是:
a - a
b - null
null - c
null - d
e - null
现在,我有以下实现:
public static IEnumerable<KeyValuePair<T, T>> Diff<T>(IEnumerable<T> a, IEnumerable<T> b, IEqualityComparer<T> comparer)
{
List<T> listA = a.ToList();
List<T> listB = b.ToList();
int indexA = 0;
int indexB = 0;
while (indexA < listA.Count || indexB < listB.Count)
{
if (indexA == listA.Count && indexB < listB.Count)
{
yield return new KeyValuePair<T, T>(default(T), listB[indexB++]);
}
else if (indexA < listA.Count && indexB == listB.Count)
{
yield return new KeyValuePair<T, T>(listA[indexA++], default(T));
}
else if (comparer.Equals(listA[indexA], listB[indexB]))
{
yield return new KeyValuePair<T, T>(listA[indexA++], listB[indexB++]);
}
else
{
yield return new KeyValuePair<T, T>(listA[indexA++], default(T));
}
}
}
产生以下输出:
a - a
b - null
e - null
null - c
null - d
任何人都可以帮助我,如何解决它(是否有任何开箱即用的 nuget 包?)
更新:
感谢@Daniel 的回答,如果集合不包含重复记录,它就可以工作。
在这种情况下,过滤重复的项目或保证没有重复不是一个选项。
我面临的下一个问题如下:
假设,我有两个集合(字符串列表):
Collection A: Collection B:
Apple Apple
Apple Peach
Peach
实际结果如下所示:
Result Collection
Apple - Apple
null - Peach
Apple - null
Peach - null
我的期望是:
Result Collection
Apple - Apple
Apple - null
Peach - Peach
在这种情况下是否可以检测和耦合元素?
解决方案
正如其他人在评论中指出的那样,您可能必须改写问题以更清楚地说明所需的输出是什么。对你想要“差异合并”做什么做一些假设,我猜你需要的不仅仅是相等比较器。平等比较器只告诉你事情是否相等。我的猜测是您要比较小于、等于和大于。
如果您必须为该方法提供自定义比较器,这是一种似是而非的实现:
public static IEnumerable<KeyValuePair<T, T>> Diff<T>(IEnumerable<T> a, IEnumerable<T> b, IComparer<T> comparer)
{
List<T> listA = a.ToList();
List<T> listB = b.ToList();
int indexA = 0;
int indexB = 0;
while (indexA < listA.Count || indexB < listB.Count)
{
if (indexA == listA.Count && indexB < listB.Count)
{
yield return new KeyValuePair<T, T>(default(T), listB[indexB++]);
}
else if (indexA < listA.Count && indexB == listB.Count)
{
yield return new KeyValuePair<T, T>(listA[indexA++], default(T));
}
else
{
int comparison = comparer.Compare(listA[indexA], listB[indexB]);
if (comparison == 0)
{
yield return new KeyValuePair<T, T>(listA[indexA++], listB[indexB++]);
}
else if (comparison < 0)
{
yield return new KeyValuePair<T, T>(listA[indexA++], default(T));
}
else
{
yield return new KeyValuePair<T, T>(default(T), listB[indexB++]);
}
}
}
}
或者您可以放弃 Comparer 参数并在 T 上添加类型约束以实现 IComparable 接口,这将是我的偏好。您的问题仍然不是所有事情都清楚,因此请彻底测试我的答案或更改问题。
推荐阅读
- svelte - 从 Svelte 的数组中动态导入 Fontawesome 图标
- php - 没有主题页眉、页脚、侧边栏的完整 Wordpress Post html、脚本和 css
- html - 如何修复这个“Tailwind CSS Deprecation”错误?
- c# - 可以做些什么来防止此 MailKit SMTP 失败?
- reactjs - reactjs中未从父级调用子组件函数
- c++ - C++ 对编译的多重定义
- tensorflow - tensorflow(lambda 文本,标签:文本)仅文本并使用 pyspark 进行调整
- bash - npm 不会安装 sass 并且无法输入密码
- c# - azure 函数应用程序中的 LINQ 子查询返回错误消息
- sql-server - 外部应用内的 WITH 语句