【问题标题】:Merging two lists with no dups合并两个没有重复的列表
【发布时间】:2012-04-17 10:38:49
【问题描述】:

我需要根据另外两个列表创建一个列表。但似乎它不会删除重复项。

这是合并两个没有重复的列表的有效方法吗?

List<String[]> blocksComparisonSet1 = new List<String[]>(); 
List<String[]> blocksComparisonSet2 = new List<String[]>(); 
//we will combine list1 and list2 into this one
List<String[]> blocksComparisonFinal = new List<String[]>(); 

//this is how I store data in each list  
//if both values found, add both of them (partial functions, FYI)
String[] NA = new String[2]; //keep results
NA[0] = baseLine; //[0] for base
NA[1] = resultLine; //[1] for result
blocksComparisonSet1.Add(NA);

//if only one value found
String[] NA = new String[2]; //keep results
NA[0] = ""; //[0] for base
NA[1] = resultLine; //[1] for result
blocksComparisonSet1.Add(NA);

//This is where I merge lists and try to remove duplicates
if (blocksComparisonSet1.Count() > 0 || blocksComparisonSet2.Count() > 0) 
//check if we have any values in out differences lists. if we do, merge them
{
    blocksComparisonFinal.AddRange(blocksComparisonSet1); 
    //add records from one list to final list
    blocksComparisonFinal.AddRange(blocksComparisonSet2); 
    //add records from second list to final list
    blocksComparisonFinal = blocksComparisonFinal.Distinct().ToList(); 
    //remove dublicates
}

-

List1[] Example    
string1 na
string2 na
string3 String1
string4 String7
string5 string8
na  string9
na  string2

-

List2[]  Example    
na  string2
na  string5
String1 string3
String7 string4
string8 string5
string9 na
string2 na

-

Final List[] must be:
na  string9
na  string2
na  string5
string1 na
String1 string3
string2 na
string3 String1
string4 String7
string5 string8
String7 string4
string8 string5
string9 na

【问题讨论】:

  • 当你的意思是Any时不要使用Count

标签: c# list optimization duplicates duplicate-removal


【解决方案1】:
var merge = blocksComparisonSet1.Union(
                blocksComparisonSet2,
                new ArrayEqualityComparer<string>()
            ).ToList();

您将需要一个自定义IEqualityComparer&lt;string[]&gt;。见MSDN

这是一个实现:

class ArrayEqualityComparer<T> : IEqualityComparer<T[]> {
    public bool Equals(T[] x, T[] y) {
        if(Object.ReferenceEquals(x, y)) {
            return true;
        }
        if(x == null || y == null) {
            return false;
        }
        return x.SequenceEqual(y);
    }

    public int GetHashCode(T[] x) {
        if(x == null) {
            return 0; 
        }
        return x.Aggregate(
            0,
            (h, item) => h ^ (item != null ? item.GetHashCode() : 0)
        );
    }
}

【讨论】:

  • 是的,你肯定需要一个 IEqualityComparer 的实现。您的代码不能按原样工作。
【解决方案2】:

另一种非 Linq 解决方案,实现为 IEqualityComparer&lt;string[]&gt;

var merged = new HashSet<string[]>(blocksComparisonSet1, new SEC());
merged.UnionWith(blocksComparisonSet2);

class SEC : IEqualityComparer<string[]>
{
    public bool Equals(string[] p1, string[] p2){
        return p1.SequenceEqual(p2);
    }
    public int GetHashCode(string[] p){ 
        return (int)p.Sum (p1 => p1.GetHashCode()); 
    }
}

【讨论】:

  • 当心!数组中可能有空的string 引用。
猜你喜欢
  • 2013-10-21
  • 2021-12-29
  • 2019-01-28
  • 1970-01-01
  • 2013-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多