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

Popular posts from this blog

dns - How To Use Custom Nameserver On Free Cloudflare? -

python - Pygame screen.blit not working -

c# - Web API response xml language -