c# - Sorting multiple collections of objects by looking at each object's own path -


this code problem , it's killing me. can't figure out how ... find myself creating temp arrays hold references, loops in loops.. it's mess.

the setup

look @ image. have 3 collections (layers) cross-references between collections.

the goal order somethings indicated arrows. however, c more important b more important (it's bottom-up importance). can change natural order following in different "layer".

imgur

so desired order is:

+----+----+----+---+---+---+---+---+----+----+----+---+---+---+---+ | 14 | 15 | 17 | 7 | 8 | 1 | 2 | 9 | 18 | 19 | 12 | 3 | 4 | 5 | 6 | +----+----+----+---+---+---+---+---+----+----+----+---+---+---+---+ 

you have few times before arrive @ same conclusion. let me break down you.

we start in layer c (c outranks b , a, remember?) ... first column on left start column. have 14, 15 , 17. don't want 18, because 18 not have reference 17. move layer , start @ beginning again 7 , 8. ends there, since 9 not reference 8.

we move 1 layer again , 1 , 2.

then gets difficult -- 2 followed 9, 9 first. see 9 followed 18, grab one. here important part -- c outranks b , a, first 19, go fetch 12 , go layer continue after 2 , 3,4,5,6.

there must ingenieus way , still keep fast. stripped down example. real thing has dozens of objects , layers.

the real thing has virtual propery completes 1-to-many relationship. want avoid property, because adds collection mix, in case make things easier i'll add here.

class {   public int id {get;set;}   public int followsid {get;set;}   public ienumerable<something> followedby {get;set;} } 

i renamed properties easier grasp.

you can treat tree structure, , walk left-to-right (or in case, nodes directly linked sublayer prior nodes same layer) ensuring yield current node before navigating sub-nodes...

working code:

public class layer {     public string name { get; set; }     public int priority { get; set; }      public head { get; set; }     public add(something s) {          if (this.head == null) this.head = s;          s.layer = this;          this.items.add(s);          return s;      }     public this[int id] {          { return this.items.singleordefault(s => s.id == id); }      }     public list<something> items = new list<something>();      private void buildtree(list<something> list, s = null)     {         list.add(s);         foreach(something ss in s.followers.orderby(sss => sss.layer.priority))         {             buildtree(list, ss);         }     }     public list<something> tree     {                  {             list<something> list = new list<something>();             if (this.head != null) buildtree(list, this.head);             return list;         }     } }  public class {     public int id { get; set; }     public layer layer { get; set; }     public list<something> followers = new list<something>();     public void follows(something s) { s.followers.add(this); } }  void main() {     layer = new layer() {          name="a",          priority = 3     };     a.add(new something() { id = 1 });     a.add(new something() { id = 2 }).follows(a[1]);     a.add(new something() { id = 3 }).follows(a[2]);     a.add(new something() { id = 4 }).follows(a[3]);     a.add(new something() { id = 5 }).follows(a[4]);     a.add(new something() { id = 6 }).follows(a[5]);      layer b = new layer() {          name = "b",         priority = 2     };     b.add(new something() { id = 7 });     b.add(new something() { id = 8 }).follows(b[7]);     b.add(new something() { id = 9 }).follows(a[2]);     b.add(new something() { id = 12 }).follows(b[9]);      layer c = new layer() {         name = "c",         priority = 1     };     c.add(new something() { id = 14 });     c.add(new something() { id = 15 }).follows(c[14]);     c.add(new something() { id = 17 }).follows(c[15]);     c.add(new something() { id = 18 }).follows(b[9]);     c.add(new something() { id = 19 }).follows(c[18]);      list<something> ordereditems = new list<something>();     list<layer> layers = new list<layer>() { a, b, c };     foreach(layer l in layers.orderby(ll => ll.priority)) ordereditems.addrange(l.tree); } 

if run in linqpad, after last line, can:

string.join(",", ordereditems.select(s => s.id.tostring())).dump(); 

to see output:

14,15,17,7,8,1,2,9,18,19,12,3,4,5,6 

Comments

Popular posts from this blog

html - Firefox flex bug applied to buttons? -

html - Missing border-right in select on Firefox -

c# - two queries in same method -