Как эффективно построить дерево из плоской конструкции?

Если вы хотите проводить строгую проверку типов, вы можете определить свои модели.

Пример файловой архитектуры.

/src
  /models
    Person.js

Person.js

export default {
  name: string,
  age: number
}

В вашем файле

Импорт Person из './models/Person.js' // Путь к Person.js

[ 112]

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

В вашем tsconfig.json ( https://www.typescriptlang.org /docs/handbook/tsconfig-json.html) вы можете добавить следующее:

из

"noImplicitAny": false,

в

"noImplicitAny": true,

137
задан Vogel612 12 January 2015 в 14:45
поделиться

5 ответов

Идентификаторы хранилища объектов в хеш-таблице, отображающейся на конкретный объект. Перечислите через все объекты и найдите их родителя, если он существует, и обновите его родительский указатель соответственно.

class MyObject
{ // The actual object
    public int ParentID { get; set; }
    public int ID { get; set; }
}

class Node
{
    public List<Node> Children = new List<Node>();
    public Node Parent { get; set; }
    public MyObject AssociatedObject { get; set; }
}

IEnumerable<Node> BuildTreeAndGetRoots(List<MyObject> actualObjects)
{
    Dictionary<int, Node> lookup = new Dictionary<int, Node>();
    actualObjects.ForEach(x => lookup.Add(x.ID, new Node { AssociatedObject = x }));
    foreach (var item in lookup.Values) {
        Node proposedParent;
        if (lookup.TryGetValue(item.AssociatedObject.ParentID, out proposedParent)) {
            item.Parent = proposedParent;
            proposedParent.Children.Add(item);
        }
    }
    return lookup.Values.Where(x => x.Parent == null);
}
110
ответ дан 23 November 2019 в 23:34
поделиться

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

0
ответ дан 23 November 2019 в 23:34
поделиться

Большинство ответов предполагает, что Вы надеетесь делать это за пределами базы данных. Если Ваши деревья относительно статичны по своей природе, и просто необходимо так или иначе отобразить деревья в базу данных, можно хотеть рассмотреть использование вложенных представлений набора на стороне базы данных. Выезд заказывает Joe Celko (или здесь для обзора Celko).

Если связано с Oracle dbs так или иначе, проверьте их ПОДКЛЮЧЕНИЕ для прямых подходов SQL.

С любым подходом Вы могли полностью пропустить отображение деревьев перед загрузкой данных в базе данных. Просто мысль, которую я предложил бы этому как альтернативе, это может быть абсолютно несоответствующим для Ваших определенных потребностей. Целый "надлежащий порядок" часть исходного вопроса несколько подразумевает необходимость в порядке быть "корректными" в дб по некоторым причинам? Это могло бы продвинуть меня к обработке деревьев там также.

1
ответ дан 23 November 2019 в 23:34
поделиться

Неопределенный, поскольку вопрос кажется мне, я, вероятно, создал бы карту от идентификатора до фактического объекта. В псевдо-Java (я не проверял, работает ли он/компилирует), это могло бы быть что-то как:

Map<ID, FlatObject> flatObjectMap = new HashMap<ID, FlatObject>();

for (FlatObject object: flatStructure) {
    flatObjectMap.put(object.ID, object);
}

И искать каждого родителя:

private FlatObject getParent(FlatObject object) {
    getRealObject(object.ParentID);
}

private FlatObject getRealObject(ID objectID) {
    flatObjectMap.get(objectID);
}

Путем многократного использования getRealObject(ID) и делая карту от объекта до набора объектов (или их идентификаторы), Вы получаете родителя->, дети отображаются также.

1
ответ дан 23 November 2019 в 23:34
поделиться

Я могу сделать это в 4 строках кода, и O (n регистрируют n), время, предполагая, что Словарь - что-то как TreeMap.

dict := Dictionary new.
ary do: [:each | dict at: each id put: each].
ary do: [:each | (dict at: each parent) addChild: each].
root := dict at: nil.

Править: Хорошо, и теперь я считал, что некоторые parentIDs являются фальшивкой, поэтому забудьте вышеупомянутое и сделайте это:

dict := Dictionary new.
dict at: nil put: OrderedCollection new.
ary do: [:each | dict at: each id put: each].
ary do: [:each | 
    (dict at: each parent ifAbsent: [dict at: nil]) 
          add: each].
roots := dict at: nil.
1
ответ дан 23 November 2019 в 23:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: