কীভাবে দক্ষতার সাথে ফ্ল্যাট কাঠামো থেকে একটি গাছ তৈরি করবেন?


153

আমার একটি সমতল কাঠামোয় একগুচ্ছ বস্তু রয়েছে। এই জিনিসগুলির একটি IDএবং একটি ParentIDসম্পত্তি রয়েছে যাতে এগুলি গাছগুলিতে সাজানো যায়। তারা কোন বিশেষ অনুক্রমে হয়। প্রতিটি ParentIDসম্পত্তি অগত্যা IDকাঠামোর সাথে কোনওটির সাথে মেলে না । সুতরাং তাদের এই বস্তু থেকে উদ্ভূত বিভিন্ন গাছ হতে পারে।

ফলস্বরূপ গাছগুলি তৈরি করতে আপনি কীভাবে এই জিনিসগুলি প্রক্রিয়া করবেন?

আমি কোনও সমাধান থেকে খুব বেশি দূরে নই তবে আমি নিশ্চিত এটি সর্বোত্তম থেকে দূরে ...

এরপরে সঠিক ক্রমে আমাকে একটি ডাটাবেসে ডেটা .োকাতে এই গাছগুলি তৈরি করতে হবে।

কোনও বিজ্ঞপ্তি উল্লেখ নেই। একটি নোড একটি রুটনোড হয় যখন প্যারেন্টআইডি == নাল হয় বা যখন প্যারেন্টআইডি অন্য বস্তুগুলিতে খুঁজে পাওয়া যায় না


"তৈরি" বলতে কী বোঝ? একটি ইউআই রেন্ডার? এক্সএমএল বা একটি ডাটাবেসে একটি শ্রেণিবিন্যাসিক ফ্যাশনে সঞ্চয় করবেন?
রেডফিল্টার

আপনি কোন পিতামাতাকে (যেমন একটি মূল নোড) দিয়ে কোনও নোডকে কীভাবে সংজ্ঞায়িত করবেন। প্যারেন্টআইডি নাল? প্যারেন্টআইডি = 0? আমি ধরে নিয়েছি কোন বিজ্ঞপ্তি উল্লেখ সঠিক নেই?
জেসন পুনিউন

5
আমি এই প্রশ্নটি বেশ শীতল মনে।
nes1983

1
এই নিবন্ধটি দেখুন: scip.be/index.php?Page=ArticlesNET23&Lang=NL
ইব্রাম খলিল

উত্তর:


120

নির্দিষ্ট অবজেক্টে ম্যাপিং হ্যাশ টেবিলের মধ্যে অবজেক্টগুলির আইডি সঞ্চয় করুন। সমস্ত বস্তুর মাধ্যমে গণনা করুন এবং যদি এটি বিদ্যমান থাকে তবে তাদের পিতামাতার সন্ধান করুন এবং সে অনুযায়ী তার পিতামাত্ত পয়েন্টারটি আপডেট করুন।

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

5
এটি কোন ভাষা? (আমি এটি সি # নিচ্ছি)
জেসন এস

3
এই আলগোটি (অনানুষ্ঠানিক স্বরলিপিতে) ও (3 এন), যেখানে কোনও 'ট্র্যাভারড' পিতা-মাতার জন্য আংশিক নোড ইনস্ট্যান্ট করে বা অ-তাত্ক্ষণিক শিশুদের জন্য সেকেন্ডারি লক-আপ টেবিল রেখে কোনও ও (1N) সমাধান সহজেই অর্জনযোগ্য v বাবা। সম্ভবত রিয়েল-ওয়ার্ল্ড ব্যবহারের ক্ষেত্রে গুরুত্বপূর্ণ নয়, তবে এটি বড় ডেটা সেটগুলিতে উল্লেখযোগ্য হতে পারে।
অ্যান্ড্রু হ্যানলন

15
@ অ্যান্ড্রুহানলন সম্ভবত আপনার 0 (1 এন)
সিড

1
নীচে @ সিড মার্টিন শ্মিটের উত্তর আমি কীভাবে এটি বাস্তবায়ন করব তার খুব কাছাকাছি is যেমন দেখা যায়, এটি একটি একক লুপ ব্যবহার করে এবং বাকিগুলি হ্যাশটেবল অপারেশন।
অ্যান্ড্রু হ্যানলন

26
ও (3 এন) কেবল ও (এন);)
জ্যাকউইলসন 801

34

মেহরদাদ আফশারীর উত্তর এবং স্পিডআপের জন্য অ্যান্ড্রু হ্যানলনের মন্তব্যের ভিত্তিতে, আমার নেওয়া এখানে।

মূল কাজের ক্ষেত্রে গুরুত্বপূর্ণ পার্থক্য: একটি রুট নোডের আইডি == প্যারেন্টআইডি রয়েছে।

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 Source { get; set; }
}

List<Node> BuildTreeAndGetRoots(List<MyObject> actualObjects)
{
    var lookup = new Dictionary<int, Node>();
    var rootNodes = new List<Node>();

    foreach (var item in actualObjects)
    {
        // add us to lookup
        Node ourNode;
        if (lookup.TryGetValue(item.ID, out ourNode))
        {   // was already found as a parent - register the actual object
            ourNode.Source = item;
        }
        else
        {
            ourNode = new Node() { Source = item };
            lookup.Add(item.ID, ourNode);
        }

        // hook into parent
        if (item.ParentID == item.ID)
        {   // is a root node
            rootNodes.Add(ourNode);
        }
        else
        {   // is a child row - so we have a parent
            Node parentNode;
            if (!lookup.TryGetValue(item.ParentID, out parentNode))
            {   // unknown parent, construct preliminary parent
                parentNode = new Node();
                lookup.Add(item.ParentID, parentNode);
            }
            parentNode.Children.Add(ourNode);
            ourNode.Parent = parentNode;
        }
    }

    return rootNodes;
}

1
ভাল লাগল, এটি মূলত আমি সেই পদ্ধতির দিকেই ইঙ্গিত করছি। তবে আমি কেবল একটি সিডো রুট নোড (আইডি = 0 এবং নাল প্যারেন্ট সহ) ব্যবহার করব এবং স্ব-রেফারেন্সের প্রয়োজনীয়তা সরিয়ে ফেলব।
অ্যান্ড্রু হ্যানলন

এই উদাহরণে অনুপস্থিত একমাত্র জিনিসটি প্রতিটি বাচ্চাদের নোডের মধ্যে পিতামাতার ক্ষেত্রটি বরাদ্দ করা হয়। এটি করতে, বাচ্চাদের অভিভাবক সংগ্রহে যোগ করার পরে কেবলমাত্র পিতামাত ক্ষেত্রটি সেট করা দরকার। লাইক তাই: প্যারেন্টনোড.চিল্ডেন.এড (আমাদের নোড); আমাদেরনোড.পিতা = পিতা-মাতা;
প্লুরিওলা

@ প্ল্যারিওলা সত্য, ধন্যবাদ, আমি এটি যুক্ত করেছি। একটি বিকল্প হ'ল প্যারেন্ট সম্পত্তি হ'ল এটি মূল অ্যালগরিদমের জন্য প্রয়োজনীয় নয়।
মার্টিন শ্মিড্ট

4
যেহেতু আমি কোনও এনপিএম মডিউলটি খুঁজে পাইনি যা একটি ও (এন) সমাধান প্রয়োগ করে, তাই আমি নিম্নলিখিতটি তৈরি করেছি (ইউনিট পরীক্ষিত, 100% কোড কভারেজ, মাত্র 0.5 কেবি আকার এবং টাইপগুলি অন্তর্ভুক্ত Maybe সম্ভবত এটি কাউকে সহায়তা করে: এনপিএমজেএস
ফিলিপ স্টানিসালাস

32

এন সময়ে চালিত পিতামাতার / শিশু গাছের কাঠামোর মধ্যে ফ্ল্যাট টেবিলটি পার্স করার জন্য এখানে একটি সাধারণ জাভাস্ক্রিপ্ট অ্যালগরিদম রয়েছে:

var table = [
    {parent_id: 0, id: 1, children: []},
    {parent_id: 0, id: 2, children: []},
    {parent_id: 0, id: 3, children: []},
    {parent_id: 1, id: 4, children: []},
    {parent_id: 1, id: 5, children: []},
    {parent_id: 1, id: 6, children: []},
    {parent_id: 2, id: 7, children: []},
    {parent_id: 7, id: 8, children: []},
    {parent_id: 8, id: 9, children: []},
    {parent_id: 3, id: 10, children: []}
];

var root = {id:0, parent_id: null, children: []};
var node_list = { 0 : root};

for (var i = 0; i < table.length; i++) {
    node_list[table[i].id] = table[i];
    node_list[table[i].parent_id].children.push(node_list[table[i].id]);
}

console.log(root);

এই পদ্ধতির সি # তে রূপান্তর করার চেষ্টা করা হচ্ছে।
হকান

বুঝতে পেরেছি যে আইডিটি যদি 1001 এর মতো বড় কিছু থেকে শুরু হয় তবে আমরা বাঁধা ব্যতিক্রম থেকে সূচি
পেলাম

2
টিপ: console.log(JSON.stringify(root, null, 2));আউটপুট প্রিন্ট করার জন্য ব্যবহার করুন ।
অ্যালোআইএসডিজি

14

পাইথন সমাধান

def subtree(node, relationships):
    return {
        v: subtree(v, relationships) 
        for v in [x[0] for x in relationships if x[1] == node]
    }

উদাহরণ স্বরূপ:

# (child, parent) pairs where -1 means no parent    
flat_tree = [
     (1, -1),
     (4, 1),
     (10, 4),
     (11, 4),
     (16, 11),
     (17, 11),
     (24, 17),
     (25, 17),
     (5, 1),
     (8, 5),
     (9, 5),
     (7, 9),
     (12, 9),
     (22, 12),
     (23, 12),
     (2, 23),
     (26, 23),
     (27, 23),
     (20, 9),
     (21, 9)
    ]

subtree(-1, flat_tree)

উত্পাদন:

{
    "1": {
        "4": {
            "10": {}, 
            "11": {
                "16": {}, 
                "17": {
                    "24": {}, 
                    "25": {}
                }
            }
        }, 
        "5": {
            "8": {}, 
            "9": {
                "20": {}, 
                "12": {
                    "22": {}, 
                    "23": {
                        "2": {}, 
                        "27": {}, 
                        "26": {}
                    }
                }, 
                "21": {}, 
                "7": {}
            }
        }
    }
}

ওহে. আউটপুটটিতে আমি কীভাবে অন্য একটি বৈশিষ্ট্য যুক্ত করব? অর্থাত। নাম, প্যারেন্ট_আইডি
সহজ লোক

এখন পর্যন্ত সবচেয়ে মার্জিত!
সিসিপিজ্জা

@ সিম্পলগুয়ে: আপনার আরও নিয়ন্ত্রণের প্রয়োজন হলে তালিকা উপলব্ধিটি প্রকাশিত হতে পারে, যেমন:def recurse(id, pages): for row in rows: if row['id'] == id: print(f'''{row['id']}:{row['parent_id']} {row['path']} {row['title']}''') recurse(row['id'], rows)
সিসিপিজ্জা

8

জেএস সংস্করণ যা একটি শিকড় বা শিকড়ের একটি অ্যারের প্রত্যাবর্তন করে যার প্রত্যেকটির সাথে সম্পর্কিত শিশুদের সমন্বয়ে একটি শিশু অ্যারে সম্পত্তি থাকবে। অর্ডার করা ইনপুট, শালীনভাবে কমপ্যাক্টের উপর নির্ভর করে না এবং পুনরাবৃত্তি ব্যবহার করে না। উপভোগ করুন!

// creates a tree from a flat set of hierarchically related data
var MiracleGrow = function(treeData, key, parentKey)
{
    var keys = [];
    treeData.map(function(x){
        x.Children = [];
        keys.push(x[key]);
    });
    var roots = treeData.filter(function(x){return keys.indexOf(x[parentKey])==-1});
    var nodes = [];
    roots.map(function(x){nodes.push(x)});
    while(nodes.length > 0)
    {

        var node = nodes.pop();
        var children =  treeData.filter(function(x){return x[parentKey] == node[key]});
        children.map(function(x){
            node.Children.push(x);
            nodes.push(x)
        });
    }
    if (roots.length==1) return roots[0];
    return roots;
}


// demo/test data
var treeData = [

    {id:9, name:'Led Zep', parent:null},
    {id:10, name:'Jimmy', parent:9},
    {id:11, name:'Robert', parent:9},
    {id:12, name:'John', parent:9},

    {id:8, name:'Elec Gtr Strings', parent:5},
    {id:1, name:'Rush', parent:null},
    {id:2, name:'Alex', parent:1},
    {id:3, name:'Geddy', parent:1},
    {id:4, name:'Neil', parent:1},
    {id:5, name:'Gibson Les Paul', parent:2},
    {id:6, name:'Pearl Kit', parent:4},
    {id:7, name:'Rickenbacker', parent:3},

    {id:100, name:'Santa', parent:99},
    {id:101, name:'Elf', parent:100},

];
var root = MiracleGrow(treeData, "id", "parent")
console.log(root)

2
এই প্রশ্নটি 7 বছরের পুরানো এবং ইতিমধ্যে একটি ভোট এবং গ্রহণযোগ্য উত্তর রয়েছে। আপনি যদি মনে করেন আপনার আরও ভাল সমাধান রয়েছে তবে আপনার কোডটিতে কিছু ব্যাখ্যা যুক্ত করা ভাল।
জর্ডি নেবোট

এই অ্যারোর্ডারযুক্ত ধরণের ডেটার জন্য এই পদ্ধতির ভাল কাজ করে।
কোডি সি

4

এখানে একটি দুর্দান্ত জাভাস্ক্রিপ্ট সংস্করণ পাওয়া গেছে: http://oskarhane.com/create-a-nested-array-recursively-in- javascript/

আসুন ধরে নেওয়া যাক আপনার কাছে এর মতো একটি অ্যারে রয়েছে:

const models = [
    {id: 1, title: 'hello', parent: 0},
    {id: 2, title: 'hello', parent: 0},
    {id: 3, title: 'hello', parent: 1},
    {id: 4, title: 'hello', parent: 3},
    {id: 5, title: 'hello', parent: 4},
    {id: 6, title: 'hello', parent: 4},
    {id: 7, title: 'hello', parent: 3},
    {id: 8, title: 'hello', parent: 2}
];

এবং আপনি অবজেক্টগুলি এভাবে বাসাতে চান:

const nestedStructure = [
    {
        id: 1, title: 'hello', parent: 0, children: [
            {
                id: 3, title: 'hello', parent: 1, children: [
                    {
                        id: 4, title: 'hello', parent: 3, children: [
                            {id: 5, title: 'hello', parent: 4},
                            {id: 6, title: 'hello', parent: 4}
                        ]
                    },
                    {id: 7, title: 'hello', parent: 3}
                ]
            }
        ]
    },
    {
        id: 2, title: 'hello', parent: 0, children: [
            {id: 8, title: 'hello', parent: 2}
        ]
    }
];

এখানে একটি পুনরাবৃত্ত ফাংশন যা এটি ঘটায় তা তৈরি করে।

function getNestedChildren(models, parentId) {
    const nestedTreeStructure = [];
    const length = models.length;

    for (let i = 0; i < length; i++) { // for-loop for perf reasons, huge difference in ie11
        const model = models[i];

        if (model.parent == parentId) {
            const children = getNestedChildren(models, model.id);

            if (children.length > 0) {
                model.children = children;
            }

            nestedTreeStructure.push(model);
        }
    }

    return nestedTreeStructure;
}

Usuage:

const models = [
    {id: 1, title: 'hello', parent: 0},
    {id: 2, title: 'hello', parent: 0},
    {id: 3, title: 'hello', parent: 1},
    {id: 4, title: 'hello', parent: 3},
    {id: 5, title: 'hello', parent: 4},
    {id: 6, title: 'hello', parent: 4},
    {id: 7, title: 'hello', parent: 3},
    {id: 8, title: 'hello', parent: 2}
];
const nestedStructure = getNestedChildren(models, 0);

প্রতিটি পিতামাতার জন্য এটি পুরো মডেলটি লুপ করছে - এটি কি ও (এন ^ 2) নয়?
এড র্যান্ডাল

4

ইউজিনের সমাধানের সি # সংস্করণে আগ্রহী প্রত্যেকের জন্য, নোড_লিস্টটি নোট করুন জন্য মানচিত্র হিসাবে অ্যাক্সেস করা হয়েছে, সুতরাং এর পরিবর্তে একটি অভিধান ব্যবহার করুন

মনে রাখবেন যে টেবিলটি প্যারেন্ট_আইড অনুসারে বাছাই করা হলেই এই সমাধানটি কাজ করে ।

var table = new[]
{
    new Node { parent_id = 0, id = 1 },
    new Node { parent_id = 0, id = 2 },
    new Node { parent_id = 0, id = 3 },
    new Node { parent_id = 1, id = 4 },
    new Node { parent_id = 1, id = 5 },
    new Node { parent_id = 1, id = 6 },
    new Node { parent_id = 2, id = 7 },
    new Node { parent_id = 7, id = 8 },
    new Node { parent_id = 8, id = 9 },
    new Node { parent_id = 3, id = 10 },
};

var root = new Node { id = 0 };
var node_list = new Dictionary<int, Node>{
    { 0, root }
};

foreach (var item in table)
{
    node_list.Add(item.id, item);
    node_list[item.parent_id].children.Add(node_list[item.id]);
}

নোড নিম্নলিখিত হিসাবে সংজ্ঞায়িত করা হয়।

class Node
{
    public int id { get; set; }
    public int parent_id { get; set; }
    public List<Node> children = new List<Node>();
}

1
এটি অনেক পুরানো তবে তালিকার আইটেম 8 সম্পূর্ণ হতে new Node { parent_id = 7, id = 9 },বাধা দেয় node_list.Add(item.id, item);কারণ কী পুনরাবৃত্তি করতে পারে না; এটি একটি টাইপো; তাই হয়, পরিবর্তে আইডি = 9 , টাইপ আইডি = 8
মার্সেলো Scofano

সংশোধন করা হয়েছে। ধন্যবাদ @ মার্সেলোস্কোফানো!
জোয়েল ম্যালোন

3

আমি সি # তে জেনেরিক সমাধানটি লিখেছিলাম মেহরদাদ আফশারি উত্তরের উপর ভিত্তি করে:

void Example(List<MyObject> actualObjects)
{
  List<TreeNode<MyObject>> treeRoots = actualObjects.BuildTree(obj => obj.ID, obj => obj.ParentID, -1);
}

public class TreeNode<T>
{
  public TreeNode(T value)
  {
    Value = value;
    Children = new List<TreeNode<T>>();
  }

  public T Value { get; private set; }
  public List<TreeNode<T>> Children { get; private set; }
}

public static class TreeExtensions
{
  public static List<TreeNode<TValue>> BuildTree<TKey, TValue>(this IEnumerable<TValue> objects, Func<TValue, TKey> keySelector, Func<TValue, TKey> parentKeySelector, TKey defaultKey = default(TKey))
  {
    var roots = new List<TreeNode<TValue>>();
    var allNodes = objects.Select(overrideValue => new TreeNode<TValue>(overrideValue)).ToArray();
    var nodesByRowId = allNodes.ToDictionary(node => keySelector(node.Value));

    foreach (var currentNode in allNodes)
    {
      TKey parentKey = parentKeySelector(currentNode.Value);
      if (Equals(parentKey, defaultKey))
      {
        roots.Add(currentNode);
      }
      else
      {
        nodesByRowId[parentKey].Children.Add(currentNode);
      }
    }

    return roots;
  }
}

নিচে ভোটার, মন্তব্য করুন। আমি কী ভুল করেছি তা জানতে পেরে খুশি হব।
হুবেজা

2

এখানে মেহরদাদ আফশারীর উত্তরটির জাভা সমাধান দেওয়া হল।

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class Tree {

    Iterator<Node> buildTreeAndGetRoots(List<MyObject> actualObjects) {
        Map<Integer, Node> lookup = new HashMap<>();
        actualObjects.forEach(x -> lookup.put(x.id, new Node(x)));
        //foreach (var item in lookup.Values)
        lookup.values().forEach(item ->
                {
                    Node proposedParent;
                    if (lookup.containsKey(item.associatedObject.parentId)) {
                        proposedParent = lookup.get(item.associatedObject.parentId);
                        item.parent = proposedParent;
                        proposedParent.children.add(item);
                    }
                }
        );
        //return lookup.values.Where(x =>x.Parent ==null);
        return lookup.values().stream().filter(x -> x.parent == null).iterator();
    }

}

class MyObject { // The actual object
    public int parentId;
    public int id;
}

class Node {
    public List<Node> children = new ArrayList<Node>();
    public Node parent;
    public MyObject associatedObject;

    public Node(MyObject associatedObject) {
        this.associatedObject = associatedObject;
    }
}

কোডটির পেছনে আপনার ধারণাটি কী তা আপনার কিছুটা ব্যাখ্যা করা উচিত।
জিয়াদ আকিকি

এটি পূর্ববর্তী উত্তরটির কেবল জাভা অনুবাদ
বিমল ভট্ট

1

প্রশ্ন হিসাবে প্রশ্নটি মনে হচ্ছে, আমি সম্ভবত আইডি থেকে আসল অবজেক্টে একটি মানচিত্র তৈরি করব। সিউডো-জাভাতে (আমি এটি কাজ করে / সংকলন করি কিনা তা পরীক্ষা করিনি), এটি এমন কিছু হতে পারে:

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

আমি কোডটি 4 টি লাইনের ও ও (এন লগ এন) সময়ে এটি করতে পারি, ধরে নিচ্ছি যে অভিধানটি একটি ট্রিম্যাপের মতো।

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.

সম্পাদনা : ঠিক আছে, এবং এখন আমি পড়েছি যে কিছু প্যারেন্টআইডি নকল, সুতরাং উপরেরটি ভুলে যান এবং এটি করুন:

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

বেশিরভাগ উত্তর ধরে নিয়েছে যে আপনি এটি ডাটাবেসের বাইরে করছেন। যদি আপনার গাছগুলি তুলনামূলকভাবে স্থিতিশীল থাকে এবং আপনার কেবল কোনওভাবে গাছগুলিকে ডাটাবেসে মানচিত্রের প্রয়োজন হয় তবে আপনি ডাটাবেসের পাশে নেস্টেট সেট উপস্থাপনাগুলি ব্যবহার করে বিবেচনা করতে পারেন। জো সেলকোর বইগুলি দেখুন (বা এখানে সেলকো দ্বারা সংক্ষিপ্তসার জন্য)।

যদি যাইহোক ওরাকল ডিবিএসের সাথে আবদ্ধ থাকে, সরাসরি এসকিউএল পদ্ধতির জন্য তাদের সংযোগটি দেখুন।

উভয় পদ্ধতির সাথে আপনি ডেটাবেজে ডেটা লোড করার আগে আপনি গাছগুলি ম্যাপিংকে পুরোপুরি এড়িয়ে যেতে পারেন। আমি ভেবেছিলাম বিকল্প হিসাবে আমি এটি উপস্থাপন করব, এটি আপনার নির্দিষ্ট প্রয়োজনের জন্য পুরোপুরি অনুপযুক্ত হতে পারে। মূল প্রশ্নের পুরো "যথাযথ ক্রম" অংশটি কিছুটা বোঝায় যে কোনও কারণে ডিবিতে আপনার "সঠিক" হওয়ার জন্য অর্ডারটি প্রয়োজন? এটি আমাকে সেইসাথে গাছগুলি পরিচালনা করার দিকেও চাপ দিতে পারে।


1

এটি অনুরোধকারীর সন্ধানের মতো হ'ল নয়, তবে এখানে প্রদত্ত দ্বিধাবিভক্ত অক্ষরযুক্ত উত্তরগুলির চারপাশে আমার মাথা মুড়িয়ে দিতে সমস্যা হয়েছিল এবং আমি এখনও মনে করি যে শিরোনামের অধীনে এই উত্তরটি খাপ খায়।

আমার উত্তরটি হ'ল সরাসরি-অন-অবজেক্ট ট্রিটিতে ফ্ল্যাট কাঠামো তৈরি করার জন্য যেখানে আপনার সমস্ত ParentIDজিনিস প্রতিটি বস্তুর উপর একটি । ParentIDহয় nullবা 0যদি এটি একটি মূল হয়। প্রশ্নকারীর বিপরীতে, আমি ParentIDতালিকার অন্য কোনও কিছুর জন্য সমস্ত বৈধের অবস্থানটি ধরে নিয়েছি :

var rootNodes = new List<DTIntranetMenuItem>();
var dictIntranetMenuItems = new Dictionary<long, DTIntranetMenuItem>();

//Convert the flat database items to the DTO's,
//that has a list of children instead of a ParentID.
foreach (var efIntranetMenuItem in flatIntranetMenuItems) //List<tblIntranetMenuItem>
{
    //Automapper (nuget)
    DTIntranetMenuItem intranetMenuItem =
                                   Mapper.Map<DTIntranetMenuItem>(efIntranetMenuItem);
    intranetMenuItem.Children = new List<DTIntranetMenuItem>();
    dictIntranetMenuItems.Add(efIntranetMenuItem.ID, intranetMenuItem);
}

foreach (var efIntranetMenuItem in flatIntranetMenuItems)
{
    //Getting the equivalent object of the converted ones
    DTIntranetMenuItem intranetMenuItem = dictIntranetMenuItems[efIntranetMenuItem.ID];

    if (efIntranetMenuItem.ParentID == null || efIntranetMenuItem.ParentID <= 0)
    {
        rootNodes.Add(intranetMenuItem);
    }
    else
    {
        var parent = dictIntranetMenuItems[efIntranetMenuItem.ParentID.Value];
        parent.Children.Add(intranetMenuItem);
        //intranetMenuItem.Parent = parent;
    }
}
return rootNodes;

1

এখানে একটি রুবি বাস্তবায়ন:

এটি বৈশিষ্ট্যটির নাম বা একটি পদ্ধতি কলের ফলাফল অনুসারে ক্যাটালগ তৈরি করবে।

CatalogGenerator = ->(depth) do
  if depth != 0
    ->(hash, key) do
      hash[key] = Hash.new(&CatalogGenerator[depth - 1])
    end
  else
    ->(hash, key) do
      hash[key] = []
    end
  end
end

def catalog(collection, root_name: :root, by:)
  method_names = [*by]
  log = Hash.new(&CatalogGenerator[method_names.length])
  tree = collection.each_with_object(log) do |item, catalog|
    path = method_names.map { |method_name| item.public_send(method_name)}.unshift(root_name.to_sym)
  catalog.dig(*path) << item
  end
  tree.with_indifferent_access
end

 students = [#<Student:0x007f891d0b4818 id: 33999, status: "on_hold", tenant_id: 95>,
 #<Student:0x007f891d0b4570 id: 7635, status: "on_hold", tenant_id: 6>,
 #<Student:0x007f891d0b42c8 id: 37220, status: "on_hold", tenant_id: 6>,
 #<Student:0x007f891d0b4020 id: 3444, status: "ready_for_match", tenant_id: 15>,
 #<Student:0x007f8931d5ab58 id: 25166, status: "in_partnership", tenant_id: 10>]

catalog students, by: [:tenant_id, :status]

# this would out put the following
{"root"=>
  {95=>
    {"on_hold"=>
      [#<Student:0x007f891d0b4818
        id: 33999,
        status: "on_hold",
        tenant_id: 95>]},
   6=>
    {"on_hold"=>
      [#<Student:0x007f891d0b4570 id: 7635, status: "on_hold", tenant_id: 6>,
       #<Student:0x007f891d0b42c8
        id: 37220,
        status: "on_hold",
        tenant_id: 6>]},
   15=>
    {"ready_for_match"=>
      [#<Student:0x007f891d0b4020
        id: 3444,
        status: "ready_for_match",
        tenant_id: 15>]},
   10=>
    {"in_partnership"=>
      [#<Student:0x007f8931d5ab58
        id: 25166,
        status: "in_partnership",
        tenant_id: 10>]}}}

1

গৃহীত উত্তরটি আমার কাছে বেশ জটিল দেখায় তাই আমি এর একটি রুবি এবং নোডজেএস সংস্করণ যুক্ত করছি

মনে করুন যে ফ্ল্যাট নোডের তালিকার নিম্নলিখিত কাঠামো রয়েছে:

nodes = [
  { id: 7, parent_id: 1 },
  ...
] # ruby

nodes = [
  { id: 7, parentId: 1 },
  ...
] # nodeJS

উপরের ফ্ল্যাট তালিকা কাঠামোটিকে একটি গাছে পরিণত করবে এমন ফাংশনগুলি নীচের উপায়ে দেখায়

রুবির জন্য:

def to_tree(nodes)

  nodes.each do |node|

    parent = nodes.find { |another| another[:id] == node[:parent_id] }
    next unless parent

    node[:parent] = parent
    parent[:children] ||= []
    parent[:children] << node

  end

  nodes.select { |node| node[:parent].nil? }

end

নোডজেএস এর জন্য:

const toTree = (nodes) => {

  nodes.forEach((node) => {

    const parent = nodes.find((another) => another.id == node.parentId)
    if(parent == null) return;

    node.parent = parent;
    parent.children = parent.children || [];
    parent.children = parent.children.concat(node);

  });

  return nodes.filter((node) => node.parent == null)

};

আমি বিশ্বাস করি চেকটি হওয়া nullদরকারundefined
উল্লৌরি

@ নোডজেএস- null == undefined => trueএ উল্লৌরি
হিরুরগ 103

1

এটি করার একটি মার্জিত উপায় হ'ল তালিকার আইটেমগুলিকে পিতামাতার বিন্দুর দ্বারা পৃথক করা তালিকা হিসাবে স্ট্রিং হিসাবে প্রতিনিধিত্ব করা এবং অবশেষে একটি মান:

server.port=90
server.hostname=localhost
client.serverport=90
client.database.port=1234
client.database.host=localhost

একটি গাছ জড়ো করার সময়, আপনি এমন কিছু দিয়ে শেষ করবেন:

server:
  port: 90
  hostname: localhost
client:
  serverport=1234
  database:
    port: 1234
    host: localhost

আমার কাছে একটি কনফিগারেশন লাইব্রেরি রয়েছে যা কমান্ড লাইন আর্গুমেন্ট (তালিকা) থেকে এই ওভাররাইড কনফিগারেশন (ট্রি) প্রয়োগ করে। গাছের তালিকায় একটি আইটেম যুক্ত করার জন্য অ্যালগরিদম এখানে


0

আপনি কি কেবল সেই বৈশিষ্ট্যগুলি ব্যবহার করে আটকে গেছেন? যদি তা না হয় তবে চাইল্ড নোডগুলির একটি অ্যারে তৈরি করা ভাল হতে পারে, যেখানে আপনি এই জাতীয় বৈশিষ্ট্যগুলি তৈরি করতে একবার এই সমস্ত বস্তুর মধ্যে চক্র রাখতে পারেন। সেখান থেকে, বাচ্চাদের সাথে নোডটি নির্বাচন করুন তবে কোনও পিতামাতা নেই এবং পুনরুক্তি করে আপনার গাছটি উপরে থেকে নীচে থেকে তৈরি করুন।


0

জাভা সংস্করণ

// node
@Data
public class Node {
    private Long id;
    private Long parentId;
    private String name;
    private List<Node> children = new ArrayList<>();
}

// flat list to tree
List<Node> nodes = new ArrayList();// load nodes from db or network
Map<Long, Node> nodeMap = new HashMap();
nodes.forEach(node -> {
  if (!nodeMap.containsKey(node.getId)) nodeMap.put(node.getId, node);
  if (nodeMap.containsKey(node.getParentId)) {
    Node parent = nodeMap.get(node.getParentId);
    node.setParentId(parent.getId());
    parent.getChildren().add(node);
  }
});

// tree node
List<Node> treeNode = nodeMap .values().stream().filter(n -> n.getParentId() == null).collect(Collectors.toList());
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.