Sorting nodes in a GoGroup

Hello,

I’d like to be able to sort existing elements within a group, so that they are sorted according to some criterion. Right now, the only way I found to change element order within a group is by using InsertAfter & InsertBefore. This is very tedious and unefficient, compared to what I would ideally like to be able to write:

public class GoObjectComparer : IComparer {...} myGroup.Sort (new GoObjectComparer);
Is there any way to acheive something like that ? I think that internally, you are using an ArrayList to store the object, which support the Sort function.

By the way, I would also make good use of such a function on other lists of elements, for instance left & right ports of GoGeneralNode.

Thank you

GoGroup.CopyArray() will return a GoObject array. You can sort that.

Then you can do:
for (int i = 0; i < sorted.Length; i++) {
group.Insert(i, sorted);
}
I haven't actually tried this, so pardon me if this doesn't do what you want.

From what I understand of the way Insert works, it is a O(n) function, thus the proposed loop has a O(n²) complexity, which make the whole algorithm O(n²), whereas sorting should only be O(n log n). Please correct me if I’m wrong.

We have some groups with many nodes, therefore I’m a bit cautious about algorithm complexity.

That’s true, but I think that particular overhead isn’t what you need to worry about.

Have you tried it anyway? How many objects will you have in a group? How often will you need to sort?

[QUOTE=walter]Have you tried it anyway?[/quote]Not yet, I had a priority switch. I’ll come back to you as soon as I have switched back to this subject.

[QUOTE=walter]How many objects will you have in a group?[/quote]At most several hundred. Most of the time, much less.[QUOTE=walter] How often will you need to sort?[/quote]Don’t know for sure yet. I would say about two or three times per seconds for a few groups at the same time in worst case scenarios.

OK, I just tried this, and I think it should be OK.

I tried sorting 10 instances of ScrollingMultiTextNode, a Demo1 example class, each containing 100 groups holding a GoText that it sorted by.
I think the sorting performance was fine, but it might be different for your application.
Here's the sorting code:
[code] myView.Document.SkipsUndoManager = true;
IComparer comparer = new ScrollingMultiTextNodeSorter(myToggle);
myToggle = !myToggle;
foreach (GoObject x in myView.Document) {
ScrollingMultiTextNode smtn = x as ScrollingMultiTextNode;
if (smtn != null) {
GoListGroup lg = smtn.ListGroup;
GoObject[] a = lg.CopyArray();
Array.Sort(a, comparer);
lg.Initializing = true;
for (int i = 0; i < a.Length; i++) {
lg.Insert(i, a);
}
lg.Initializing = false;
lg.LayoutChildren(null);
}
}
myView.Document.SkipsUndoManager = false;
[/code]
And the IComparer:
[code] public class ScrollingMultiTextNodeSorter : IComparer {
public ScrollingMultiTextNodeSorter(bool up) { myUp = up; }
private bool myUp;
public int Compare(Object x, Object y) {
GoGroup m = (GoGroup)x; // each child is itself a GoGroup
GoGroup n = (GoGroup)y;
GoText a = m[1] as GoText; // of which the second child is a GoText
GoText b = n[1] as GoText;
if (a != null) {
if (b != null) {
String at = a.Text;
String bt = b.Text;
return myUp ? at.CompareTo(bt) : -at.CompareTo(bt);
} else {
return 1;
}
} else {
if (b != null)
return -1;
else
return 0;
}
}
}
[/code]