/// <summary> /// Sort on the head of the node /// </summary> /// <param name="other"></param> /// <returns></returns> public int CompareTo(object other) { DeckDueNode rhs = (DeckDueNode)other; // Consider each subdeck name in the ordering for (int i = 0; i < Names.Length && i < rhs.Names.Length; i++) { int cmp = Names[i].CompareTo(rhs.Names[i]); if (cmp == 0) { continue; } return(cmp); } // If we made it this far then the arrays are of different length. The longer one should // always come after since it contains all of the sections of the shorter one inside it // (i.e., the short one is an ancestor of the longer one). if (rhs.Names.Length > Names.Length) { return(-1); } else { return(1); } }
private List <DeckDueNode> GroupChildrenMain(List <DeckDueNode> grps) { List <DeckDueNode> tree = new List <DeckDueNode>(); for (int i = 0; i < grps.Count; i++) { DeckDueNode node = grps[i]; string head = node.Names[0]; // Compose the "tail" node list. The tail is a list of all the nodes that proceed // the current one that contain the same name[0]. I.e., they are subdecks that stem // from this node. This is our version of python's itertools.groupby. List <DeckDueNode> tail = new List <DeckDueNode>(); tail.Add(node); while (i < grps.Count - 1) { i++; DeckDueNode next = grps[i]; if (head.Equals(next.Names[0])) { // Same head - add to tail of current head. tail.Add(next); } else { // We've iterated past this head, so step back in order to use this node as the // head in the next iteration of the outer loop. i--; break; } } long?did = null; int rev = 0; int _new = 0; int lrn = 0; List <DeckDueNode> children = new List <DeckDueNode>(); foreach (DeckDueNode c in tail) { if (c.Names.Length == 1) { // current node did = c.DeckId; rev += c.ReviewCount; lrn += c.LearnCount; _new += c.NewCount; } else { // set new string to tail string[] newTail = new string[c.Names.Length - 1]; Array.Copy(c.Names, 1, newTail, 0, c.Names.Length - 1); c.Names = newTail; children.Add(c); } } children = GroupChildrenMain(children); // tally up children counts foreach (DeckDueNode ch in children) { rev += ch.ReviewCount; lrn += ch.LearnCount; _new += ch.NewCount; } // limit the counts to the deck's limits if (did == null) { throw new Exception("Schedule.GroupChildrenMain Did is null"); } JsonObject conf = collection.Deck.ConfForDeckId((long)did); JsonObject deck = collection.Deck.Get(did); if (JsonHelper.GetNameNumber(conf, "dyn") == 0) { rev = Math.Max(0, Math.Min(rev, (int)(JsonHelper.GetNameNumber(conf.GetNamedObject("rev"), "perDay") - deck.GetNamedArray("revToday").GetNumberAt(1)))); _new = Math.Max(0, Math.Min(_new, (int)(JsonHelper.GetNameNumber(conf.GetNamedObject("new"), "perDay") - deck.GetNamedArray("newToday").GetNumberAt(1)))); } tree.Add(new DeckDueNode(head, (long)did, rev, lrn, _new, children)); } return(tree); }