То, что вы хотите сделать, - это преобразовать плоский список объектов в рекурсивную иерархию узлов, где каждый узел задается некоторым уникальным именем в контексте его родителя.Вы пометили свой вопрос структуры данных , поэтому вы ищете модель данных, которая облегчит построение такой иерархии.
Обобщая немного, каждый узел должен выглядеть следующим образомследующее:
public abstract partial class HierarchicalNode<TItem, THierarchicalNode>
where THierarchicalNode : HierarchicalNode<TItem, THierarchicalNode>, new()
{
public IDictionary<string, THierarchicalNode> Children { get; private set; }
public ICollection<TItem> Items { get; private set; }
public HierarchicalNode()
{
this.Children = new Dictionary<string, THierarchicalNode>();
this.Items = new List<TItem>();
}
}
Здесь узел содержит:
Список объектов типа TItem
.(Для этого вы будете использовать string
.)
Словарь дочерних узлов того же типа.Здесь мы используем словарь, чтобы гарантировать отсутствие дубликатов в именах пространства имен.
Я определил Items
как список, но если вам нужно также предотвратить дублирование элементовВы можете заменить конкретную реализацию на HashSet<TItem>
Вам также понадобится некоторая рекурсивная логика для построения иерархии.Следующее должно сделать трюк:
public partial class HierarchicalNode<TItem, THierarchicalNode>
{
public THierarchicalNode GetOrAddChild(string namespaceName)
{
THierarchicalNode child;
if (!Children.TryGetValue(namespaceName, out child))
child = Children[namespaceName] = new THierarchicalNode();
return child;
}
public void AddObject(IList<string> nodeNames, TItem item)
{
AddObject(nodeNames, 0, item);
}
void AddObject(IList<string> nodeNames, int index, TItem item)
{
if (index >= nodeNames.Count)
Items.Add(item);
else
{
GetOrAddChild(nodeNames[index]).AddObject(nodeNames, index + 1, item);
}
}
}
Здесь уместным методом является AddObject(IList<string> nodeNames, TItem item)
, который добавляет объект, который находится во вложенном списке узлов, заданном списком имен.
Наконец, поскольку вас интересуют пространства имен, вы должны определить свой конкретный тип следующим образом:
public class Namespace : HierarchicalNode<string, Namespace>
{
}
и создать корень Namespace
следующим образом:
// Deserialize the JSON shown in the question to an array of objects with Namespace and Name properties
var list = JsonConvert.DeserializeAnonymousType(
jsonString,
new[] { new { Namespace = default(string), Name = default(string) } });
var root = new Namespace();
foreach (var item in list)
{
// Split the Namespace property into an array for recursive processing
root.AddObject(item.Namespace.Split('.'), item.Name);
}
Демо-скрипка здесь .