From 861150142345acd6c460e972a5d04ab0780c10e6 Mon Sep 17 00:00:00 2001 From: Kyle Spearrin Date: Thu, 29 Nov 2018 19:42:24 -0500 Subject: [PATCH] nested tree node traversal helpers --- src/App/Abstractions/ITreeNodeObject.cs | 8 ++++ src/App/Models/TreeNode.cs | 19 ++++++++ src/App/Utilities/Helpers.cs | 62 +++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 src/App/Abstractions/ITreeNodeObject.cs create mode 100644 src/App/Models/TreeNode.cs diff --git a/src/App/Abstractions/ITreeNodeObject.cs b/src/App/Abstractions/ITreeNodeObject.cs new file mode 100644 index 000000000..8c29a67f6 --- /dev/null +++ b/src/App/Abstractions/ITreeNodeObject.cs @@ -0,0 +1,8 @@ +namespace Bit.App.Abstractions +{ + public interface ITreeNodeObject + { + string Id { get; set; } + string Name { get; set; } + } +} diff --git a/src/App/Models/TreeNode.cs b/src/App/Models/TreeNode.cs new file mode 100644 index 000000000..e06e2f41b --- /dev/null +++ b/src/App/Models/TreeNode.cs @@ -0,0 +1,19 @@ +using Bit.App.Abstractions; +using System.Collections.Generic; + +namespace Bit.App.Models +{ + public class TreeNode where T : ITreeNodeObject + { + public TreeNode(T node, string name, T parent) + { + Parent = parent; + Node = node; + Node.Name = name; + } + + public T Parent { get; set; } + public T Node { get; set; } + public List> Children { get; set; } = new List>(); + } +} diff --git a/src/App/Utilities/Helpers.cs b/src/App/Utilities/Helpers.cs index 663f604b3..c659034a3 100644 --- a/src/App/Utilities/Helpers.cs +++ b/src/App/Utilities/Helpers.cs @@ -569,5 +569,67 @@ namespace Bit.App.Utilities var appSettingsService = Resolver.Resolve(); return appSettingsService?.OrganizationGivesPremium ?? false; } + + public static void NestedTraverse(List> nodeTree, int partIndex, string[] parts, + ITreeNodeObject obj, ITreeNodeObject parent, string delimiter) + { + if(parts.Length <= partIndex) + { + return; + } + + var end = partIndex == parts.Length - 1; + var partName = parts[partIndex]; + + foreach(var n in nodeTree) + { + if(n.Node.Name != parts[partIndex]) + { + continue; + } + if(end && n.Node.Id != obj.Id) + { + // Another node with the same name. + nodeTree.Add(new TreeNode(obj, partName, parent)); + return; + } + NestedTraverse(n.Children, partIndex + 1, parts, obj, n.Node, delimiter); + return; + } + + if(!nodeTree.Any(n => n.Node.Name == partName)) + { + if(end) + { + nodeTree.Add(new TreeNode(obj, partName, parent)); + return; + } + var newPartName = string.Concat(parts[partIndex], delimiter, parts[partIndex + 1]); + var newParts = new List { newPartName }; + var newPartsStartFrom = partIndex + 2; + newParts.AddRange(new ArraySegment(parts, newPartsStartFrom, parts.Length - newPartsStartFrom)); + NestedTraverse(nodeTree, 0, newParts.ToArray(), obj, parent, delimiter); + } + } + + public static TreeNode GetTreeNodeObject(List> nodeTree, string id) + { + foreach(var n in nodeTree) + { + if(n.Node.Id == id) + { + return n; + } + else if(n.Children != null) + { + var node = GetTreeNodeObject(n.Children, id); + if(node != null) + { + return node; + } + } + } + return null; + } } }