Laden...

Hierarchy-Struct ähnlich SqlHierarchyId

Erstellt von jaensen vor 10 Jahren Letzter Beitrag vor 10 Jahren 3.687 Views
jaensen Themenstarter:in
2.760 Beiträge seit 2006
vor 10 Jahren
Hierarchy-Struct ähnlich SqlHierarchyId

Beschreibung:
Ich musste neulich ein paar Datensätze unter Beachtung der ihrer Hierarchie sortieren und brauchte dafür einen kleinen Helfer den ich hier gerne zur Verfügung stelle:

        public struct Hierarchy : IComparable
        {
            private int[] _parts;

            public Hierarchy(string path, string seperator = "/")
            {
                if (path == null)
                    throw new ArgumentNullException("path");
                if (seperator == null)
                    throw new ArgumentNullException("seperator");

                string[] pathParts = path.Split(new string[] { seperator }, StringSplitOptions.RemoveEmptyEntries);
                _parts = new int[pathParts.Length];

                for (int i = 0; i < pathParts.Length; i++)
                {
                    int parsed = 0;
                    if (!int.TryParse(pathParts[i], out parsed))
                        throw new Exception("The input path has the wrong format. Allowed format is: /int/int/int or int/int/int");

                    _parts[i] = parsed;
                }
            }

            public static bool operator >(Hierarchy h1, Hierarchy h2)
            {
                int l = h1._parts.Length >= h2._parts.Length ? h1._parts.Length : h2._parts.Length;

                for (int i = 0; i < l; i++)
                {
                    if (i > h1._parts.Length - 1 || i > h2._parts.Length - 1)
                        break;

                    int v1 = h1._parts[i];
                    int v2 = h2._parts[i];

                    if (v1 == v2)
                        continue;

                    return v1 > v2;
                }

                return false;
            }

            public static bool operator <(Hierarchy h1, Hierarchy h2)
            {
                int l = h1._parts.Length >= h2._parts.Length ? h1._parts.Length : h2._parts.Length;

                for (int i = 0; i < l; i++)
                {
                    if (i > h1._parts.Length - 1 || i > h2._parts.Length - 1)
                        break;

                    int v1 = h1._parts[i];
                    int v2 = h2._parts[i];

                    if (v1 == v2)
                        continue;

                    return v1 < v2;
                }

                return false;
            }

            public static bool operator ==(Hierarchy h1, Hierarchy h2)
            {
                if (h1._parts.Length != h2._parts.Length)
                    return false;

                for (int i = 0; i < h1._parts.Length; i++)
                {
                    if (h1._parts[i] != h2._parts[i])
                        return false;
                }

                return true;
            }

            public static bool operator !=(Hierarchy h1, Hierarchy h2)
            {
                if (h1._parts.Length != h2._parts.Length)
                    return true;

                for (int i = 0; i < h1._parts.Length; i++)
                {
                    if (h1._parts[i] == h2._parts[i])
                        return false;
                }

                return true;
            }

            public int CompareTo(object obj)
            {
                if (!(obj is Hierarchy))
                    return 1;

                Hierarchy h = (Hierarchy)obj;
                if (h > this)
                    return 1;
                else if (h < this)
                    return -1;
                else
                    return 0;
            }

            public override bool Equals(object obj)
            {
                if (!(obj is Hierarchy))
                    return false;

                Hierarchy h = (Hierarchy)obj;
                return h == this;
            }

            public override int GetHashCode()
            {
                unchecked
                {
                    int hash = 0;
                    for (int i = 0; i < _parts.Length; i++)
                    {
                        hash = i ^ _parts[i] + hash;
                    }
                    return hash;
                }
            }
        }

Verwendung läuft folgendermaßen:


            Hierarchy h1 = new Hierarchy("/123/123/123/123/123/123");
            Hierarchy h2 = new Hierarchy("123/123/123/123/123/123");
            Hierarchy h3 = new Hierarchy("123/123/123/123/123/123/");

            // h1 == h2 = true
            // h2 == h3 = true

           Hierarchy h4 = new Hierarchy(".123.123.123.123.123.123", ".");
           // h3 == h4 = true

Schlagwörter: Hierarchie, Baum, Tree, sortieren, Sortierung