sorting - Optimize algorithm: Update a collection by other collection with order C# -


problem: have collection need update other collection. length of them not equal , each item not same structure. both of them have identity field detect same.

i write generic algorithm use everywhere complexity o(m*n*3). main problem is: there better optimization algorithm? input must should generic ilist<t> , delegate reusable.

current approach:

  • source: data collection used display on gui.

  • target: data collection got remote server.

    1. remove old items source doesn't existed target via delegate comparer.
    2. add new items target source.
    3. reorder source target.

scenario usage: if have application display 1~2k row on list view. , have interval timer update list item (about 1 seconds). main point here application should smooth, doesn't flick , keep state of object: selected, change data... etc.

here source code:

using system; using system.collections.generic; using system.linq;  namespace updatecollection {     /// <summary>     /// person dto (from other 3rd assembly) data remote server.     /// </summary>     public class persondto     {         public int id { get; set; }         public string name { get; set; }         public datetime birthday { get; set; }     }      /// <summary>     /// person model used display on gui (our application).     /// </summary>     public class personmodel     {         public string identity { get; set; }         public string displayname { get; set; }         public int? age { get; set; }         public bool selected { get; set; }         public override string tostring()         {             return string.format("{0} {1} {2} {3}", identity, displayname, age, selected);         }     }      static class program     {         /// <summary>         /// encapsulates method has 2 parameters , not return value.         /// </summary>         /// <typeparam name="t1">the type of first parameter of method delegate encapsulates.this     type parameter contravariant. is, can use either type specified or type less derived. more information covariance , contravariance, see covariance , contravariance in generics.</typeparam>         /// <typeparam name="t2">the type of second parameter of method delegate encapsulates.</typeparam>         /// <param name="arg1"></param>         /// <param name="arg2"></param>         public delegate void refaction<t1, in t2>(ref t1 arg1, t2 arg2);          /// todo: complexity of algorithm is: o(m*n*3) need optimization. example: m*log2(n)+ m + n         /// <summary>         /// update source target.         /// </summary>         /// <typeparam name="tsourcetype"></typeparam>         /// <typeparam name="ttargettype"></typeparam>         /// <param name="source">source collection.</param>         /// <param name="target">target collection.</param>         /// <param name="compare">comparing method between source , target.</param>         /// <param name="convert">convert method</param>         /// <param name="update">update method</param>         /// <param name="remove">remove method</param>         public static void updateby<tsourcetype, ttargettype>(             ilist<tsourcetype> source,             ilist<ttargettype> target,             func<tsourcetype, ttargettype, bool> compare,             func<ttargettype, tsourcetype> convert,             refaction<tsourcetype, ttargettype> update,             func<tsourcetype, bool> remove = null)         {             if (source == null || target == null)                 return;              if (convert == null)                 throw new aggregateexception("convert");             if (compare == null)                 throw new argumentnullexception("compare");              // remove item             (var index = 0; index < source.count; ++index)             {                 if (target.any(c => compare(source[index], c))) continue;                 var temp = source[index];                 if (remove == null)                     source.removeat(index--);                 else if (remove(temp))                     source.removeat(index--);             }             // add new item             foreach (var t in target.where(t => !source.any(c => compare(c, t))))             {                 source.add(convert(t));             }             // sort target             (var index = 0; index < target.count; ++index)             {                 (var pos = 0; pos < source.count; ++pos)                 {                     if (!compare(source[pos], target[index])) continue;                      var temp = source[pos];                     if (update != null)                         update(ref temp, target[index]);                     source[pos] = temp;                      if (pos == index) continue;                      temp = source[pos];                     source[pos] = source[index];                     source[index] = temp;                 }             }         }          public static ilist<personmodel> getfromuserinterface()         {             return new list<personmodel>             {                 new personmodel {identity = "1", displayname = "a",},                 new personmodel {identity = "2", displayname = "b", selected = true},                 new personmodel {identity = "3", displayname = "c", selected = true},                 new personmodel {identity = "4", displayname = "d"}             };         }          public static ilist<persondto> getfromremoteserver()         {             return new list<persondto>             {                 new persondto {id = 6, name = "f", birthday = datetime.parse("1984-01-02")},                 new persondto {id = 4, name = "d", birthday = datetime.parse("1986-01-12")},                 new persondto {id = 3, name = "c", birthday = datetime.parse("1982-03-05")},                 new persondto {id = 5, name = "e", birthday = datetime.parse("1984-05-22")},                 new persondto {id = 1, name = "a", birthday = datetime.parse("1986-02-14")}             };         }          public static bool compare(personmodel source, persondto target)         {             return source.identity == target.id.tostring();         }          public static personmodel convert(persondto target)         {             return new personmodel             {                 identity = target.id.tostring(),                 age = target.birthday.year,                 displayname = target.name,             };         }          public static void update(ref personmodel source, persondto target)         {             source.age = target.birthday.year;             source.displayname = target.name;         }          static void main(string[] args)         {              var source = getfromuserinterface();             var target = getfromremoteserver();              console.writeline("==> before update:\r\n");             foreach (var item in source)                 console.write("{0}\r\n\r\n", item);              // todo: how optimize updateby algorithm better?             source.updateby(target, compare, convert, update);              console.writeline("==> after update:\r\n");              foreach (var item in source)                 console.write("{0}\r\n\r\n", item);              console.readline();         }     } } 

you storing data in list; switching hash table structure give (roughly) constant time access members key. if ordering of data important, many languages have kind of ordered hash construct can use.


Comments