Nano Hash - криптовалюты, майнинг, программирование

Удалить элемент во вложенных коллекциях N-го уровня

У меня возникли проблемы с попыткой удалить элемент внутри объекта с древовидной структурой.

Мой объект, как показано ниже

TreeNode
{
    string name;
    ObservableCollection<TreeNode> Children;
}

Я думал, что если я рекурсивно обработаю дерево, найду свой узел и удалю его, но столкнулся с проблемой.

Я сделал что-то вроде

Обновлено:

DeleteNode(ObservableCollection<TreeNode> children, TreeNode nodetodelete)
{
    if(children.remove(nodetodelete))
    {
        return;
    }
    else
    {
        foreach(var child in children)
        {
            DeleteNode(child, nodetodelete);
        }
    }
}

Пока я писал код, я понял, что в конечном итоге столкнусь с исключением манипуляции при переборе коллекции, которая может быть изменена.
Я мог бы создать гигантское изменение циклов for, поскольку я точно знаю максимальную глубокую длину ( который я сделал для заполнителя), но это кажется очень плохим. . . .
Может ли кто-нибудь указать мне лучшее общее направление. Мне как бы интересно, является ли моя структура данных причиной этого.

Обновлять:

Это будет выглядеть ужасно и немного пахнуть кодом, но я заставил рекурсию «работать», выбрасывая исключение, когда я нахожу свой узел.

DeleteNode(children, nodetodelete)
    {
        if(children.remove(nodetodelete)
        {
            throw FoundException();
        }
        else
        {
            foreach(var child in children)
            {
                DeleteNode(child, nodetodelete)
            }
        }
    }

Есть ли другой способ выйти из рекурсии.

07.06.2015

  • Известно ли вам заранее, что узел появится в дереве только один раз? 07.06.2015
  • @Andrew Эндрю, если вы говорите о дубликатах, они могут быть дубликатами, поскольку на определенном уровне у меня есть узел-заполнитель для группировки элементов. 07.06.2015
  • Можете ли вы опубликовать свой реальный, точный код? То, что вы разместили здесь, даже не скомпилируется. 07.06.2015
  • Я думаю, что видел, как кто-то опубликовал ответ, но он был удален, что коллекцией нельзя манипулировать в цикле foreach. Я бы хотел, чтобы этот человек не удалил свой комментарий, чтобы я мог отдать ему должное. . . 07.06.2015
  • возможный дубликат Как добавить или удалить объект во время итерации Коллекция в C# 07.06.2015

Ответы:


1

Я бы справился с этим, внеся небольшое изменение в свой дизайн (при условии, что фрагмент в вашем вопросе является псевдокодом для класса):

TreeNode
{
    string name;
    TreeNode Parent;
    ObservableCollection<TreeNode> Children;

    public void Delete()
    {
        Parent.Children.Remove(this);
    }
}

Это немного усложнит вам работу по поддержанию дополнительной ссылки при манипулировании графом объектов, но сэкономит вам много усилий и кода при выполнении таких действий, как удаление, как вы можете видеть выше.

Вы не показали, как строите TreeNode, но я бы сделал родителя и коллекцию для дочерних аргументов конструктора.

07.06.2015
  • Очень элегантное решение! 16.10.2015

  • 2

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

    DeleteNode(ObservableCollection<TreeNode> children, TreeNode nodetodelete)
    {
        if (children.remove(nodetodelete))
        {
            return;
        }
        else
        {
            foreach (var child in children.ToArray())
            {
                // If anything is deleted in the collection, it will not break the iteration here, as we are iterating over an Array and not "children"
                DeleteNode(child, nodetodelete);
            }
        }
    }
    

    Это создаст новую коллекцию для повторения. Если дочерний узел удален из children, цикл foreach не вызовет исключения. Это связано с тем, что исходная коллекция была изменена, а мы перебираем вторичную коллекцию.

    07.06.2015
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..