假設我有兩個相同類別的串列。
public class emailfilter
{
public string from {get;set;}
public string to {get;set;}
public string cc {get;set;}
public string subj {get;set;}
public string body {get;set;}
public string emailid {get;set;}
}
//there are two lists of type emailfilter. 1 list is formed dynamically from the config file
List<emailfilter> configfilterlist = //mock sudo code//
{
efilter tempobj = new efilter();
tempobj.from = config.from or "" if no value
tempobj.to = config.to or "" if no value
tempobj.cc = config.cc or "" if no value
tempobj.subj = config.subj or "" if no value
tempobj.body = config.body or "" if no value
configfilterlist.add(tempobj);
}
//List1 will never have an emailID
//List2 is formed from email items pulled from exchange and made into efilter objects and those do have an emailid.
//List2 will typically have all object fields populated. List1, the object fields are optional
因此,我想將過濾器專案的 list1 與電子郵件專案的 list2 進行比較/相交,以形成一個沒有重復項的組合串列,該串列僅包含具有 list1 的所有過濾條件并包含 list2 的 mailid 的專案。如果 List1 上的值沒有值,我想忽略它,只匹配提供的配置值,跳過任何 "" 空白字串。我希望有一種方法可以使用 lambda 和 linq 來做到這一點,但我還沒有看到任何關于多個值的比較示例,并且在這種情況下忽略了其他類似 emailID 的示例。
更新:感謝@wertzui 提供解決此問題所需的答案。最終的解決方案略有不同,因此基本上用最終的解決方案更新帖子/問題,以防它幫助另一個迷失的靈魂。
public class emailfilter: IEquatable<emailfilter>
{
public string from { get; set; }
public string to { get; set; }
public string cc { get; set; }
public string subj { get; set; }
public string body { get; set; }
public string emailid { get; set; }
public override int GetHashCode()
{
return System.HashCode.Combine(from, to, cc, subj, body);
}
public override bool Equals(object? obj) => Equals(obj as emailfilter);
public bool Equals(emailfilter? other)
{
return
other != null &&
(from.Contains(other.from) || other.from == "") &&
(to.Contains(other.sentto) || other.to == "") &&
(cc.Contains(other.cc) || other.cc == "") &&
(subj.Contains(other.subj) || other.subj == "") &&
(body.Contains(other.body) || other.body == "");
}
}
//emailsasfilters is List2 = all exchange emails as filter objects
var combinedSet = new HashSet<emailfilter>();
foreach (var filter in configfilterlist) //configfilterlist is List1 = filters from Config
{
if (emailsasfilters.Contains(filter))
combinedSet.Add(emailsasfilters.ElementAt(emailsasfilters.IndexOf(filter)));
}
combinedSet.Dump();
uj5u.com熱心網友回復:
從 .Net 6 開始,UnionBy您可以使用一種新方法。
var combined = configfilterlist
.UnionBy(
exchangefilterlist,
e => new { e.from, e.to, e.cc, e.subj, e.body })
.ToList();
另一種適用于舊框架版本的方法是,使用HashSet<T>并實作GetHashCode和Equals
public class emailfilter: IEquatable<emailfilter>
{
public string from { get; set; }
public string to { get; set; }
public string cc { get; set; }
public string subj { get; set; }
public string body { get; set; }
public string emailid { get; set; }
public override int GetHashCode()
{
return System.HashCode.Combine(from, to, cc, subj, body);
}
public override bool Equals(object? obj) => Equals(obj as emailfilter);
public bool Equals(emailfilter? other)
{
return
other != null &&
from == other.from &&
to == other.to &&
cc == other.cc &&
subj == other.subj &&
body == other.body;
}
}
var combinedSet = new HashSet<emailfilter>(configfilterlist);
foreach (var email in exchangefilterlist)
{
combinedSet.Add(email);
}
combinedSet.Dump();
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/442857.html
