[英]How do I merge two lists in a single list without taking union or join in C # without duplicates?
[英]Attempting to merge two Lists<> via Union. Still have duplicates
我有兩個列表:
List<L1>, List<L2>
L1 = { detailId = 5, fileName = "string 1" }{ detailId = 5, fileName = "string 2" }
L2 = { detailId = 5, fileName = "string 2" }{ detailId = 5, fileName = "string 3" }
我希望將它們組合在一起,而不是重復:
List<L3>
L1 = { detailId = 5, fileName = "string 1" }{ detailId = 5, fileName = "string 2" }{ detailId = 5, fileName = "string 3" }
我試過了:
L1.Union(L2).ToList();
L1.Concat(L2).Distinct().ToList();
但兩者都返回重復(1,2,3,3)。
不知道我錯過了什么。
編輯這是方法。 它需要一個列表並從分隔的字符串創建另一個列表,並嘗試將它們組合在一起。
private List<Files> CombineList(int detailId, string fileNames)
{
List<Files> f1 = new List<Files>();
List<Files> f2 = new List<Files>();
f1 = GetFiles(detailId, false);
if (f1[0].fileNames != "")
{
string[] names = fileNames.Split('|');
for (int i = 0; i < names.Length; i++)
{
Files x = new Files();
x.detailId = detailId;
x.fileNames = names[i];
f2.Add(x);
}
List<Files> f3 = f1.Union(f2).ToList();
}
return f3;
}
來自MSDN,對於Union:
默認的相等比較器Default用於比較實現IEqualityComparer(Of T)泛型接口的類型的值。 要比較自定義數據類型,您需要實現此接口並為該類型提供自己的GetHashCode和Equals方法。
由於您使用自定義類型,因此您需要覆蓋GetHashCode
和Equals
或者提供實現IEqualityComparer接口的對象(最好是IEquatable
)並將其作為第二個參數提供給Union
。
我不喜歡覆蓋Files類equals對象和getHashCode,因為你干擾了對象。 讓另一個對象執行此操作並將其傳入。這樣如果以后遇到問題,只需將其交換出來並傳遞另一個IEqualityComparer這是一個可以測試的示例
public void MainMethod()
{
List<Files> f1 = new List<Files>() { new Files() { detailId = 5, fileName = "string 1" }, new Files() { detailId = 5, fileName = "string 2" } };
List<Files> f2 = new List<Files>() { new Files() { detailId = 5, fileName = "string 2" }, new Files() { detailId = 5, fileName = "string 3" } };
var f3 = f1.Union(f2, new FilesComparer()).ToList();
foreach (var f in f3)
{
Console.WriteLine(f.detailId + " " + f.fileName);
}
}
public class Files
{
public int detailId;
public string fileName;
}
public class FilesComparer : IEqualityComparer<Files>
{
public bool Equals(Files x, Files y)
{
return x.fileName == y.fileName;
}
public int GetHashCode(Files obj)
{
return obj.fileName.GetHashCode();
}
}
如果你的元素沒有實現某種比較接口(Object.Equals,IEquatable,IComparable等),那么它們之間的任何相等性測試都將涉及ReferenceEquals
,其中兩個不同的對象是兩個不同的對象,即使它們的所有成員都包含相同的值。
如果要合並對象列表,則需要為等式比較定義一些條件。 以下示例演示了這一點:
class MyModelTheUniqueIDComparer : IEqualityComparer<MyModel>
{
public bool Equals(MyModel x, MyModel y)
{
return x.SomeValue == y.SomeValue && x.OtherValue == y.OtherValue;
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public int GetHashCode(MyModel myModel)
{
unchecked
{
int hash = 17;
hash = hash * 31 + myModel.SomeValue.GetHashCode();
hash = hash * 31 + myModel.OtherValue.GetHashCode();
return hash;
}
}
}
然后你可以打電話來得到結果:
var result = q1.Union(q2, new MyModelTheUniqueIDComparer());
如果要比較自定義數據類型的對象序列,則必須在類中實現IEqualityComparer <T>泛型接口。
特定於Files
類的示例實現,以便在合並兩個自定義類型集合時, Union
可以正常工作:
public class Files : IEquatable<Files>
{
public string fileName { get; set; }
public int detailId { get; set; }
public bool Equals(Files other)
{
//Check whether the compared object is null.
if (Object.ReferenceEquals(other, null)) return false;
//Check whether the compared object references the same data.
if (Object.ReferenceEquals(this, other)) return true;
//Check whether the products' properties are equal.
return detailId.Equals(other.detailId) && fileName.Equals(other.fileName);
}
// If Equals() returns true for a pair of objects
// then GetHashCode() must return the same value for these objects.
public override int GetHashCode()
{
//Get hash code for the fileName field if it is not null.
int hashFileName = fileName == null ? 0 : fileName.GetHashCode();
//Get hash code for the detailId field.
int hashDetailId = detailId.GetHashCode();
//Calculate the hash code for the Files object.
return hashFileName ^ hashDetailId;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.