示例#1
0
        /// <inheritdoc />
        public override ITreeNode <T> Union(ITreeNode <T> other, DEquality <ITreeNode <T> > equality, DMerge <T> merge)
        {
            // if there not equal, Union results in null
            if (!equality(this, other))
            {
                return(null);
            }

            // Create a new node using the provided merge rule.
            // The merge rule determines how equal values resolve
            TreeNode <T> unionTree = new TreeNode <T>(merge(Value, other.Value));

            // Get the children of the other node, to test against the children of the current node
            List <ITreeNode <T> > testNodes = new List <ITreeNode <T> >(other.Children);

            // Foreach node in Children, preform a test to determine the case and handle
            // the union calculation
            foreach (ITreeNode <T> child in Children)
            {
                // candidates for a deeper union are testsNodes that equal the child
                IEnumerable <ITreeNode <T> > candidates = testNodes.Where(n => equality(n, child));

                // if no candidates, add this child to the new tree
                if (candidates == null || candidates.Count() == 0)
                {
                    child.Copy(unionTree);
                    continue;
                }

                // Determine which candidate should be used to perform the union
                // This is the most similar candidate
                ITreeNode <T> chosenCandidate = null;

                if (candidates.Count() == 1)
                {
                    chosenCandidate = candidates.First();
                }
                else
                {
                    chosenCandidate = child.MostSimilar(candidates);
                }

                // Perform a union with the chosen candidate
                InternalAddChild(unionTree, child.Union(chosenCandidate, equality, merge) as TreeNode <T>);

                // Remove the candidate
                testNodes.Remove(chosenCandidate);
            }

            // Add all remaining nodes without performing a merge
            foreach (ITreeNode <T> node in testNodes)
            {
                node.Copy(unionTree);
            }

            return(unionTree);
        }
示例#2
0
 /// <inheritdoc />
 public abstract ITreeNode <T> Union(ITreeNode <T> other, DEquality <ITreeNode <T> > equality, DMerge <T> merge);
示例#3
0
        /// <inheritdoc />
        public override ITreeNode <T> Union(ITreeNode <T> other, DEquality <ITreeNode <T> > equality, DMerge <T> merge)
        {
            // if not equal, return null
            if (!equality(this, other))
            {
                return(null);
            }

            // since values are equal, if they both have no children, return node with value
            if (ChildCount == 0 && other.ChildCount == 0)
            {
                return(new UniqueChildrenTreeNode <T>(merge(Value, other.Value)));
            }

            // return copy of node with children if only 1 has children
            if (ChildCount > 0 && other.ChildCount == 0)
            {
                return(Copy());
            }

            if (other.ChildCount > 0 && ChildCount == 0)
            {
                return(other.Copy());
            }

            // set up the union tree for recursive calculation
            UniqueChildrenTreeNode <T> unionTree = new UniqueChildrenTreeNode <T>(merge(Value, other.Value));

            // sort out children in both that have no equivalent in other
            // perform a union on any nodes that match
            List <ITreeNode <T> > otherNodesNotInOriginal = new List <ITreeNode <T> >(other.Children);
            List <ITreeNode <T> > originalNodesNotInOther = new List <ITreeNode <T> >();

            foreach (ITreeNode <T> child in Children)
            {
                ITreeNode <T> matchingOtherNode = otherNodesNotInOriginal.Find(n => equality(n, child));

                if (matchingOtherNode == default(ITreeNode <T>))
                {
                    originalNodesNotInOther.Add(child);
                }
                else
                {
                    UniqueChildrenTreeNode <T> newUnion
                        = child.Union(matchingOtherNode) as UniqueChildrenTreeNode <T>;

                    if (newUnion == null)
                    {
                        continue;
                    }

                    // add union of matching nodes to tree
                    UnsafeAddChild(unionTree, newUnion);
                    otherNodesNotInOriginal.Remove(matchingOtherNode);
                }
            }

            // copy other nodes missing from original
            foreach (ITreeNode <T> node in otherNodesNotInOriginal)
            {
                node.Copy(unionTree);
            }

            // copy original nodes missing from other
            foreach (ITreeNode <T> node in originalNodesNotInOther)
            {
                node.Copy(unionTree);
            }

            return(unionTree);
        }