首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >C#中的泛型列表比较

C#中的泛型列表比较
EN

Stack Overflow用户
提问于 2015-12-08 16:39:32
回答 4查看 1.1K关注 0票数 1

我有一种方法,它使用字典查找两个ints列表之间的差异。本质上,代码循环第一个列表,将每个int添加到字典中,并设置(在尚未出现的情况下为1)/incrementing值。然后循环第二个列表设置(在尚未出现的情况下为-1 ),/decrementing值。

一旦它循环了这两个列表,您将得到一个字典,其中值=0的键表示匹配,值>=1的键仅表示第一个列表中的存在,值<=-1仅表示第二个列表中的存在。

第一,这是否一个明智的做法?

其次,我想使它更加通用,目前它只能处理基于int的列表。我希望能处理调用者可能定义比较逻辑的任何对象.

代码语言:javascript
运行
复制
    public static Dictionary<int, int> CompareLists(List<int> listA, List<int> listB)
    {
        // 0        Match
        // <= -1    listB only
        // >= 1     listA only
        var recTable = new Dictionary<int, int>();

        foreach (int value in listA)
        {
            if (recTable.ContainsKey(value))
                recTable[value]++;
            else
                recTable[value] = 1;
        }

        foreach (int value in listB)
        {
            if (recTable.ContainsKey(value))
                recTable[value]--;
            else
                recTable[value] = -1;
        }

        return recTable;

    }

提前感谢!

在回应:时说:“如果您的值在listA中出现两次,在listB中出现一次,结果将是肯定的,它将不能正常工作,在您的评论中只显示"listA”。“

让我澄清一下;如果一个值在listA中出现两次,那么它也应该在listB中出现两次--所以如果一个值在listA中出现两次,在listB中出现一次,那么我不关心它从listA选择匹配哪个值,只要正确地报告了一个不对齐项。

假设在用例中,您试图在两个文件之间调节大量的支付金额,有重复的金额是完全可行的,但是只要报告了不调节的值,那么重复的金额匹配到哪一个并不重要。

EN

回答 4

Stack Overflow用户

发布于 2015-12-08 16:53:20

为了回答你的第二个问题,下面是如何使它更加通用:

代码语言:javascript
运行
复制
public static Dictionary<T, int> CompareLists<T>(IEnumerable<T> listA, 
    IEnumerable<T> listB, IEqualityComparer<T> comp)
{
    var recTable = new Dictionary<T, int>(comp);

    foreach (var value in listA)
    {
        if (recTable.ContainsKey(value))
            recTable[value]++;
        else
            recTable[value] = 1;
    }

    foreach (var value in listB)
    {
        if (recTable.ContainsKey(value))
            recTable[value]--;
        else
            recTable[value] = -1;
    }

    return recTable;
}

这是比较通用的,因为:

  • 我传入T型,而不是int型。
  • 我使用IEnumerables而不是列表。
  • 我传入一个IEqualityComparer并将其传递给字典构造函数,后者需要使用它。
  • 我在foreach循环中使用var,而不是int。您也可以使用T

你把这段代码叫做:

代码语言:javascript
运行
复制
static void Main()
{
    int[] arr1 = { 1, 2, 3 };
    int[] arr2 = { 3, 2, 1 };

    var obj = CompareLists(arr1, arr2, EqualityComparer<int>.Default);

    Console.ReadLine();
}

下面是一个实现IEqualityComparer的示例。这将所有奇数ints视为相等,而将所有偶数ints视为相等:

代码语言:javascript
运行
复制
public class MyEq : IEqualityComparer<int>
{
    public bool Equals(int x, int y)
    {
        return (x % 2) == (y % 2);
    }

    public int GetHashCode(int obj)
    {
        return (obj % 2).GetHashCode();
    }
}
票数 1
EN

Stack Overflow用户

发布于 2015-12-08 16:57:11

在这里发现的FullOuterJoin:LINQ - Full Outer Join

代码语言:javascript
运行
复制
public static Dictionary<int, int> CompareLists(List<int> listA, List<int> listB)
{
  return listA.FullOuterJoin(listB,
    a=>a, // What to compare from ListA
    b=>b, // What to compare from ListB
    (a,b,key)=>
      new {key=key,value=0}, // What to return if found in both
      new {key=key,value=-1},// What to return if found only in A
      new {key=key,value=1}) // What to return if found only in B
    .ToDictionary(a=>a.key,a=>a.value); // Only because you want a dictionary
}
票数 1
EN

Stack Overflow用户

发布于 2015-12-08 16:52:45

您可以使用Generics来完成这一任务:

代码语言:javascript
运行
复制
public static Dictionary<T, int> CompareLists<T>(List<T> listA, List<T> listB)
{
    // 0        Match
    // <= -1    listB only
    // >= 1     listA only
    var recTable = new Dictionary<T, int>();

    foreach (T value in listA)
    {
        if (recTable.ContainsKey(value))
            recTable[value]++;
        else
            recTable[value] = 1;
    }

    foreach (T value in listB)
    {
        if (recTable.ContainsKey(value))
            recTable[value]--;
        else
            recTable[value] = -1;
    }

    return recTable;

}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34161261

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档