Как отформатировать этот список пространств имен в структурированный объект без дубликатов? - PullRequest
0 голосов
/ 16 декабря 2018

Итак, у меня есть список объектов, которые содержат это свойство пространства имен.Я пытаюсь сгруппировать список в объект, который не содержит дубликатов и имеет следующую структуру:

Core
   Util
      Log
      Fetch
   Math
      Add
      Subtract

Список ввода будет выглядеть следующим образом:

[
  {
    Namespace: "Core.Util",
    Name: "Log"
  },
  {
    Namespace: "Core.Util",
    Name: "Fetch"
  },
  {
    Namespace: "Core.Math",
    Name: "Add"
  },
  {
    Namespace: "Core.Math",
    Name: "Subtract"
  }
]

Ответы [ 2 ]

0 голосов
/ 17 декабря 2018

То, что вы хотите сделать, - это преобразовать плоский список объектов в рекурсивную иерархию узлов, где каждый узел задается некоторым уникальным именем в контексте его родителя.Вы пометили свой вопрос , поэтому вы ищете модель данных, которая облегчит построение такой иерархии.

Обобщая немного, каждый узел должен выглядеть следующим образомследующее:

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>();
    }
}

Здесь узел содержит:

  1. Список объектов типа TItem.(Для этого вы будете использовать string.)

  2. Словарь дочерних узлов того же типа.Здесь мы используем словарь, чтобы гарантировать отсутствие дубликатов в именах пространства имен.

  3. Я определил 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);
}

Демо-скрипка здесь .

0 голосов
/ 17 декабря 2018

Предполагая, что вы анализируете JSON с помощью JSON.Net в объекты, вы можете использовать Linq для группировки их по свойству "Пространство имен":

 var results = jsonObjects.GroupBy(o => new { Core = o.Namespace.Split('.')[0], Sub = o.Namespace.Split('.')[1] });

Это даст вам 2 группы (Core.Util иCore.Math) с 2 записями каждая.Я не знаю, что именно вы подразумеваете под «без дубликатов», но я предлагаю вам взглянуть на оператор LINQ Distinct () -.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...