I created a class to compare to generic list by one property.
public class ListComparator<TOriginal,TNew>
{
public ListComparator(IEnumerable<TOriginal> iOriginalList, Func<TOriginal, IComparable> iOriginalProperty, IEnumerable<TNew> iNewList, Func<TNew, IComparable> iNewProperty)
{
if (iOriginalProperty == null ||
iNewProperty == null) { throw new ArgumentNullException(); };
if (iOriginalList.IsNullOrEmpty() )
{
NewList = (iNewList != null) ? iNewList.ToList() : null;
return;
}
if (iNewList.IsNullOrEmpty())
{
RemovedList = (iOriginalList != null) ? iOriginalList.ToList() : null;
return;
}
NewList = (from tnew in iNewList.ToList()
join toriginal in iOriginalList.ToList()
on iNewProperty(tnew)
equals iOriginalProperty(toriginal) into gj
from item in gj.DefaultIfEmpty()
where item == null
select tnew).ToList();
CommunList = (from tnew in iNewList.ToList()
join toriginal in iOriginalList.ToList()
on iNewProperty(tnew)
equals iOriginalProperty(toriginal) into gj
from item in gj.DefaultIfEmpty()
where item != null
select tnew).ToList();
CommunPairList = (from tnew in iNewList.ToList()
join toriginal in iOriginalList.ToList()
on iNewProperty(tnew)
equals iOriginalProperty(toriginal) into gj
from item in gj.DefaultIfEmpty()
where item != null
select new KeyValuePair<TOriginal, TNew>(item, tnew)).ToList();
RemovedList = (from toriginal in iOriginalList.ToList()
join tnew in iNewList.ToList()
on iOriginalProperty(toriginal)
equals iNewProperty(tnew) into gj
from item in gj.DefaultIfEmpty()
where item == null
select toriginal).ToList();
return;
}
#region PROPRIETES
public List<TNew> NewList { get; private set; }
public List<TOriginal> RemovedList { get; private set; }
public List<TNew> CommunList { get; private set; }
/// <summary>
/// Obtient la liste de pair avec l'original en key et le nouveau en value
/// </summary>
public List<KeyValuePair<TOriginal,TNew>> CommunPairList { get; private set; }
#endregion
I use it like this:
List<Tuple<string, string>> list1 = new List<Tuple<string, string>>();
List<Tuple<string, string>> list2 = new List<Tuple<string, string>>();
list1.Add(new Tuple<string, string>("AA", "zefzef"));
list1.Add(new Tuple<string, string>("A1", "iulyu"));
list2.Add(new Tuple<string, string>("Abb", "szefez"));
list2.Add(new Tuple<string, string>("A1", "zevzez"));
ListComparator<Tuple<string, string>, Tuple<string, string>> comp = new ListComparator<Tuple<string, string>, Tuple<string, string>>(list1, x => x.Item1, list2, a => a.Item1);
Output: 1 commun 1 new 1 removed
My problem is when I replace tuple by keyValuePair
List<KeyValuePair<string, string>> list1 = new List<KeyValuePair<string, string>>();
List<KeyValuePair<string, string>> list2 = new List<KeyValuePair<string, string>>();
list1.Add(new KeyValuePair<string, string>("AA", "zefzef"));
list1.Add(new KeyValuePair<string, string>("A1", "iulyu"));
list2.Add(new KeyValuePair<string, string>("Abb", "szefez"));
list2.Add(new KeyValuePair<string, string>("A1", "zevzez"));
ListComparator<KeyValuePair<string, string>, KeyValuePair<string, string>> comp = new ListComparator<KeyValuePair<string, string>, KeyValuePair<string, string>>(list1, x => x.Key, list2, a => a.Key);
I get the input : commun 2
I don't understand .... why ? How to correct it ? Thanks
The reason for this is that KeyValuePair is a struct rather than a class- meaning a value rather than reference type. This means that default(KeyValuePair<string,string>) isn't null, so the lines where item == null and where item != null don't work as expected
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With