c# - Improving Generic List Comparator -


i need generic class compare 2 list instances. have code below, quite messy , inefficient. how can make better , faster?

callbyname extension uses reflection property.

public class listobjectcomparator {      #region proprietes      public list<object> newlist {get; private set;}     public list<object> removedlist { get; private set; }     public list<object> communlist { get; private set; }      #endregion       #region methodes publics      public bool run<t>(string icommuntextpropertyname, list<t> ioriginallist, list<t> inewlist)     {         return run(icommuntextpropertyname, ioriginallist, icommuntextpropertyname, inewlist);     }      public bool run<t>(string ioriginalpropertyname, list<t> ioriginallist,string inewpropertyname, list<t> inewlist)     {         if (ioriginalpropertyname.isnotnull() &&             inewpropertyname.isnotnull() &&             ioriginallist != null &&             inewlist != null)         {             newlist = new list<object>();             removedlist = new list<object>();             communlist = new list<object>();              foreach (object originalitem in ioriginallist)             {                 object research = inewlist.where(a => a.callbyname(inewpropertyname).tostring() == originalitem.callbyname(ioriginalpropertyname).tostring()).firstordefault();                 if (research == null)                 {                     removedlist.add(originalitem);                 }                 else                 {                     communlist.add(research);                 }             }              foreach (object newitem in inewlist)             {                 object research = ioriginallist.where(a => a.callbyname(ioriginalpropertyname).tostring() == newitem.callbyname(inewpropertyname).tostring()).firstordefault();                 if (research == null) { newlist.add(newitem); };              }             return true;         }         return false;     } } 

answer:

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) gj                        item in gj.defaultifempty()                        item == null                        select tnew).tolist();              communlist = (from tnew in inewlist.tolist()                           join toriginal in ioriginallist.tolist()                           on inewproperty(tnew)                           equals ioriginalproperty(toriginal) gj                           item in gj.defaultifempty()                           item != null                           select tnew).tolist();              communpairlist = (from tnew in inewlist.tolist()                               join toriginal in ioriginallist.tolist()                               on inewproperty(tnew)                               equals ioriginalproperty(toriginal) gj                               item in gj.defaultifempty()                               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) gj                            item in gj.defaultifempty()                            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  } 

use:

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.item1); 

output :

1 commun, 1 removed, 1 new

thanks

to list of items 2 lists share in common, @ enumerable.intersect. is:

var same = originallist.intersect(newlist, comparer); 

if want know items in newlist aren't in originallist (i.e. list of added items), you'd use enumerable.except:

var added = newlist.except(originallist, comparer); 

if want know items deleted, use except again, switch order:

var deleted = originallist.except(newlist, comparer); 

if you're comparing different properties, best bet create intermediate lists contain properties , references objects. example: (there might typos in code, shows general idea.)

class tempobj: iequatable<tempobj> {     public string key { get; set; }     public object item { get; set; }     public bool equals(tempobj other)     {         return key.equals(other.key);     }     public override int gethashcode()     {         return key.gethashcode();     } }  var listorig = originallist.select(x => new tempobj(     x..callbyname(ioriginalpropertyname).tostring()); var listnew = newlist.select(x => new tempobj(     x.callbyname(inewpropertyname).tostring()); 

now can intersect or except on listnew , listorig, compare property names. can pull item values resulting list.


Comments

Popular posts from this blog

java - Intellij Synchronizing output directories .. -

git - Initial Commit: "fatal: could not create leading directories of ..." -