दिलचस्प पोस्ट
स्क्रिप्ट टैग के प्रकार विशेषता के लिए जावास्क्रिप्ट एमआईएम प्रकार क्या है? Accordion तालिका सेल – कैसे गतिशील विस्तार / अनुबंध uitableviewcell करने के लिए? पायथन urllib2 बेसिक एथ समस्या SQL सर्वर: तालिका में पंक्तियों की अधिकतम संख्या कम करें, गुना या स्कैन करें (बाएं / दाएं)? क्रॉस-ब्राउज़र (IE8-) जावास्क्रिप्ट के साथ संक्रमित शैली प्राप्त करें? eval-after-load बनाम मोड हुक एक ggplot में कुछ किंवदंतियों को बंद करना संरेखित करें ggplot2 भूखंडों खड़ी सीरियल वीरियोनयूआईडी क्या है और मुझे इसका उपयोग क्यों करना चाहिए? आरएक्सजेएस का इस्तेमाल करते हुए रीफ्रेश टोकन को संभालना आप WiX 3 में एक Win32 COM DLL फ़ाइल कैसे पंजीकृत करते हैं? AngularJS – आइटम को सशर्त रूप से वापस करने के लिए एनजी-दोहर के साथ एक कस्टम फ़िल्टर की संरचना कैसे करें क्या JSON को .asmx वेब सेवा से वापस लौटा सकता हूं यदि ContentType JSON नहीं है? कैसे POSIX श में स्क्रिप्ट निर्देशिका प्राप्त करने के लिए?

जावास्क्रिप्ट में फ्लैट सरणी से पेड़ सरणी बनाएं

मेरे पास एक जटिल जेएसएन्स फाइल है जिसे मुझे जावास्क्रिप्ट के साथ संभाल करना है ताकि इसे पदानुक्रमित किया जा सके, ताकि बाद में एक पेड़ का निर्माण हो सके। जेएसन की हर प्रविष्टि है: आईडी: एक अनन्य आईडी, पेरेंटआईडी: पेरेंट नोड का आईडी (जो 0 है अगर नोड पेड़ की जड़ है) स्तर: पेड़ में गहराई का स्तर

जेसन डेटा पहले से ही "ऑर्डर किया गया" है मेरा मतलब है कि एक प्रविष्टि में एक माता पिता नोड या भाई नोड होगा, और अपने आप में एक बच्चे नोड या एक भाई नोड।

इनपुट:

{ "People": [ { "id": "12", "parentId": "0", "text": "Man", "level": "1", "children": null }, { "id": "6", "parentId": "12", "text": "Boy", "level": "2", "children": null }, { "id": "7", "parentId": "12", "text": "Other", "level": "2", "children": null }, { "id": "9", "parentId": "0", "text": "Woman", "level": "1", "children": null }, { "id": "11", "parentId": "9", "text": "Girl", "level": "2", "children": null } ], "Animals": [ { "id": "5", "parentId": "0", "text": "Dog", "level": "1", "children": null }, { "id": "8", "parentId": "5", "text": "Puppy", "level": "2", "children": null }, { "id": "10", "parentId": "13", "text": "Cat", "level": "1", "children": null }, { "id": "14", "parentId": "13", "text": "Kitten", "level": "2", "children": null }, ] } 

अपेक्षित उत्पादन :

 { "People": [ { "id": "12", "parentId": "0", "text": "Man", "level": "1", "children": [ { "id": "6", "parentId": "12", "text": "Boy", "level": "2", "children": null }, { "id": "7", "parentId": "12", "text": "Other", "level": "2", "children": null } ] }, { "id": "9", "parentId": "0", "text": "Woman", "level": "1", "children": { "id": "11", "parentId": "9", "text": "Girl", "level": "2", "children": null } } ], "Animals": [ { "id": "5", "parentId": "0", "text": "Dog", "level": "1", "children": { "id": "8", "parentId": "5", "text": "Puppy", "level": "2", "children": null } }, { "id": "10", "parentId": "13", "text": "Cat", "level": "1", "children": { "id": "14", "parentId": "13", "text": "Kitten", "level": "2", "children": null } } ] } 

वेब के समाधान से एकत्रित समाधान "जावास्क्रिप्ट में फ्लैट सरणी से पेड़ सरणी बनाएं"

यदि आप मानचित्र-लुकअप का उपयोग करते हैं तो एक कुशल समाधान है। यदि माता-पिता हमेशा अपने बच्चों से पहले आते हैं तो आप दो छोरों के लिए मर्ज कर सकते हैं। यह कई जड़ें का समर्थन करता है यह शाखाएं लटकने पर एक त्रुटि देता है, लेकिन उन्हें अनदेखा करने के लिए संशोधित किया जा सकता है। इसमें तीसरे पक्ष के पुस्तकालय की आवश्यकता नहीं है। यह, जहां तक ​​मैं बता सकता हूं, सबसे तेज समाधान

 function list_to_tree(list) { var map = {}, node, roots = [], i; for (i = 0; i < list.length; i += 1) { map[list[i].id] = i; // initialize the map list[i].children = []; // initialize the children } for (i = 0; i < list.length; i += 1) { node = list[i]; if (node.parentId !== "0") { // if you have dangling branches check that map[node.parentId] exists list[map[node.parentId]].children.push(node); } else { roots.push(node); } } return roots; } var entries = [ { "id": "12", "parentId": "0", "text": "Man", "level": "1" }, { /*...*/ } ]; console.log(list_to_tree(entries)); 

यदि आप जटिलता सिद्धांत में हैं तो यह समाधान Θ (n लॉग (एन)) है। पुनरावर्ती फिल्टर समाधान Θ (n ^ 2) है जो बड़े डेटा सेट के लिए एक समस्या हो सकता है।

जैसा @ सैंडर द्वारा वर्णित है, @ हैल्सीन का जवाब एक पूर्व-क्रमबद्ध सरणी को ग्रहण करता है, निम्नलिखित नहीं है। (हालांकि यह माना जाता है कि आपने अंडरस्कोर लोड किया है। जेएस – हालांकि इसे वेनिला जावास्क्रिप्ट में लिखा जा सकता है):

कोड

 unflatten = function( array, parent, tree ){ tree = typeof tree !== 'undefined' ? tree : []; parent = typeof parent !== 'undefined' ? parent : { id: 0 }; var children = _.filter( array, function(child){ return child.parentid == parent.id; }); if( !_.isEmpty( children ) ){ if( parent.id == 0 ){ tree = children; }else{ parent['children'] = children; } _.each( children, function( child ){ unflatten( array, child ) } ); } return tree; } 

आवश्यकताएँ

यह माना जाता है कि गुण 'आईडी' और 'अभिभावक' क्रमशः आईडी और अभिभावक आईडी दर्शाते हैं। माता-पिता आईडी 0 के साथ तत्व होना चाहिए, अन्यथा आपको खाली सरणी वापस मिलनी चाहिए। अनाथ तत्व और उनके वंशज 'खो गए' हैं

उदाहरण उपयोग

 //Array to convert to tree structure. var arr = [ {'id':1 ,'parentid' : 0}, {'id':2 ,'parentid' : 1}, {'id':3 ,'parentid' : 1}, {'id':4 ,'parentid' : 2}, {'id':5 ,'parentid' : 0}, {'id':6 ,'parentid' : 0}, {'id':7 ,'parentid' : 4} ]; tree = unflatten( arr ); 

JSFiddle

http://jsfiddle.net/LkkwH/1/

एक ही समस्या थी, लेकिन मुझे यकीन नहीं हो सका कि डेटा सॉर्ट किया गया है या नहीं । मैं एक तृतीय पक्ष पुस्तकालय का उपयोग नहीं कर सका इसलिए यह सिर्फ वेनिला जेएस है; @ स्टीफन के उदाहरण से इनपुट डेटा लिया जा सकता है;

 function unflatten(arr) { var tree = [], mappedArr = {}, arrElem, mappedElem; // First map the nodes of the array to an object -> create a hash table. for(var i = 0, len = arr.length; i < len; i++) { arrElem = arr[i]; mappedArr[arrElem.id] = arrElem; mappedArr[arrElem.id]['children'] = []; } for (var id in mappedArr) { if (mappedArr.hasOwnProperty(id)) { mappedElem = mappedArr[id]; // If the element is not at the root level, add it to its parent array of children. if (mappedElem.parentid) { mappedArr[mappedElem['parentid']]['children'].push(mappedElem); } // If the element is at the root level, add it to first level elements array. else { tree.push(mappedElem); } } } return tree; } 

जेएस फ्रेडल

ट्री के लिए फ्लैट ऐरे

एक और सरल फ़ंक्शन सूची टू ट्री-लाइट

npm install list-to-tree-lite

listToTree(list)

स्रोत:

 function listToTree(data, options) { options = options || {}; var ID_KEY = options.idKey || 'id'; var PARENT_KEY = options.parentKey || 'parent'; var CHILDREN_KEY = options.childrenKey || 'children'; var tree = [], childrenOf = {}; var item, id, parentId; for (var i = 0, length = data.length; i < length; i++) { item = data[i]; id = item[ID_KEY]; parentId = item[PARENT_KEY] || 0; // every item may have children childrenOf[id] = childrenOf[id] || []; // init its children item[CHILDREN_KEY] = childrenOf[id]; if (parentId != 0) { // init its parent's children object childrenOf[parentId] = childrenOf[parentId] || []; // push it into its parent's children object childrenOf[parentId].push(item); } else { tree.push(item); } }; return tree; } 

jsfiddle

यह उपयोगी पैकेज सूची टू ट्री हो सकता है स्थापित करें:

 bower install list-to-tree --save 

या

 npm install list-to-tree --save 

उदाहरण के लिए, सूची है:

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

पैकेज सूची-टू-ट्री का उपयोग करें:

 var ltt = new LTT(list, { key_id: 'id', key_parent: 'parent' }); var tree = ltt.GetTree(); 

परिणाम:

 [{ "id": 1, "parent": 0, "child": [ { "id": 2, "parent": 1, "child": [ { "id": 4, "parent": 2 }, { "id": 5, "parent": 2 } ] }, { "id": 3, "parent": 1 } ] }, { "id": 6, "parent": 0 }, { "id": 7, "parent": 0, "child": [ { "id": 8, "parent": 7, "child": [ { "id": 9, "parent": 8 } ] } ] }, { "id": 10, "parent": 0 }]; 

आप इस प्रश्न को सिर्फ दो पंक्ति कोडिंग के साथ संभाल सकते हैं:

 _(flatArray).forEach(f=> {f.nodes=_(flatArray).filter(g=>g.parentId==f.id).value();}); var resultArray=_(flatArray).filter(f=>f.parentId==null).value(); 

टेस्ट ऑनलाइन (निर्मित पेड़ के लिए ब्राउज़र कंसोल देखें)

आवश्यकताएँ:

1- लॉंडश 4 इंस्टॉल करें (ऑब्जेक्ट को छेड़छाड़ करने के लिए जावास्क्रिप्ट लाइब्रेरी और निष्पादक विधियों => की तरह Linq in c #) Lodash

2- नीचे की तरह एक फ्लैट ऐरे:

  var flatArray= [{ id:1,parentId:null,text:"parent1",nodes:[] } ,{ id:2,parentId:null,text:"parent2",nodes:[] } , { id:3,parentId:1,text:"childId3Parent1",nodes:[] } , { id:4,parentId:1,text:"childId4Parent1",nodes:[] } , { id:5,parentId:2,text:"childId5Parent2",nodes:[] } , { id:6,parentId:2,text:"childId6Parent2",nodes:[] } , { id:7,parentId:3,text:"childId7Parent3",nodes:[] } , { id:8,parentId:5,text:"childId8Parent5",nodes:[] }]; 

श्री बाखशाब्दी का धन्यवाद

सौभाग्य

पूरा करने का बहुत आसान तरीका है

(बोनस 1: नोड्स मई या मई का आदेश नहीं दिया जा सकता है)

(बोनस 2: सं 3 डीआर पार्टी लाइब्रेरी की आवश्यकता, सादा जे.एस.)

 const createDataTree = dataset => { let hashTable = Object.create(null) dataset.forEach( aData => hashTable[aData.ID] = { ...aData, childNodes : [] } ) let dataTree = [] dataset.forEach( aData => { if( aData.parentID ) hashTable[aData.parentID].childNodes.push(hashTable[aData.ID]) else dataTree.push(hashTable[aData.ID]) } ) return dataTree } 

यहां इसके लिए टेस्ट है, इससे मदद मिल सकती है:

 it('creates a correct shape of dataTree', () => { let dataSet = [ { "ID": 1, "Phone": "(403) 125-2552", "City": "Coevorden", "Name": "Grady" }, { "ID": 2, "parentID": 1, "Phone": "(979) 486-1932", "City": "Chełm", "Name": "Scarlet" } ] let expectedDataTree = [ { "ID": 1, "Phone": "(403) 125-2552", "City": "Coevorden", "Name": "Grady", childNodes : [ { "ID": 2, "parentID": 1, "Phone": "(979) 486-1932", "City": "Chełm", "Name": "Scarlet", childNodes : [] } ] } ] expect( createDataTree(dataSet) ).toEqual(expectedDataTree) }); 

यहां एक साधारण सहायक फ़ंक्शन है जिसे मैंने ऊपर दिए गए उत्तरों के बाद एक बैबल वातावरण के अनुरूप बनाया है:

 import { isEmpty } from 'lodash' export default function unflattenEntities(entities, parent = {id: null}, tree = []) { let children = entities.filter( entity => entity.parent_id == parent.id) if (!isEmpty( children )) { if ( parent.id == null ) { tree = children } else { parent['children'] = children } children.map( child => unflattenEntities( entities, child ) ) } return tree } 

यह भी लैंडशज के साथ करते हैं (v4.x)

 function buildTree(arr){ var a=_.keyBy(arr, 'id') return _ .chain(arr) .groupBy('parentId') .forEach(function(v,k){ k!='0' && (a[k].children=(a[k].children||[]).concat(v)); }) .result('0') .value(); } 

यहां स्टीवन हैरिस का एक संशोधित संस्करण है जो सादे ईएस 5 है और आईडी पर एक ऑब्जेक्ट को रिटर्न देता है, नोडों को शीर्ष स्तर और बच्चों के दोनों ओर लौटने की बजाय।

 unflattenToObject = function(array, parent) { var tree = {}; parent = typeof parent !== 'undefined' ? parent : {id: 0}; var childrenArray = array.filter(function(child) { return child.parentid == parent.id; }); if (childrenArray.length > 0) { var childrenObject = {}; // Transform children into a hash/object keyed on token childrenArray.forEach(function(child) { childrenObject[child.id] = child; }); if (parent.id == 0) { tree = childrenObject; } else { parent['children'] = childrenObject; } childrenArray.forEach(function(child) { unflattenToObject(array, child); }) } return tree; }; var arr = [ {'id':1 ,'parentid': 0}, {'id':2 ,'parentid': 1}, {'id':3 ,'parentid': 1}, {'id':4 ,'parentid': 2}, {'id':5 ,'parentid': 0}, {'id':6 ,'parentid': 0}, {'id':7 ,'parentid': 4} ]; tree = unflattenToObject(arr); 

यह अतारांकित वस्तुओं के लिए एक प्रस्ताव है यह फ़ंक्शन एक एकल पाश और एक हैश तालिका के साथ काम करता है और अपने id साथ सभी आइटम एकत्र करता है। यदि कोई रूट नोड पाया जाता है, तो ऑब्जेक्ट को परिणाम सरणी में जोड़ा जाता है।

 function getTree(data, root) { var r = [], o = {}; data.forEach(function (a) { if (o[a.id] && o[a.id].children) { a.children = o[a.id].children; } o[a.id] = a; if (a.parentId === root) { r.push(a); } else { o[a.parentId] = o[a.parentId] || {}; o[a.parentId].children = o[a.parentId].children || []; o[a.parentId].children.push(a); } }); return r; } var data = { People: [{ id: "12", parentId: "0", text: "Man", level: "1", children: null }, { id: "6", parentId: "12", text: "Boy", level: "2", children: null }, { id: "7", parentId: "12", text: "Other", level: "2", children: null }, { id: "9", parentId: "0", text: "Woman", level: "1", children: null }, { id: "11", parentId: "9", text: "Girl", level: "2", children: null }], Animals: [{ id: "5", parentId: "0", text: "Dog", level: "1", children: null }, { id: "8", parentId: "5", text: "Puppy", level: "2", children: null }, { id: "10", parentId: "13", text: "Cat", level: "1", children: null }, { id: "14", parentId: "13", text: "Kitten", level: "2", children: null }] }, tree = Object.keys(data).reduce(function (r, k) { r[k] = getTree(data[k], '0'); return r; }, {}); console.log(tree); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

यह उपरोक्त का एक संशोधित संस्करण है जो कई जड़ वस्तुओं के साथ काम करता है, मैं अपने आईडी और माता-पिता आईडी के लिए GUID का उपयोग करता हूं ताकि यूआई में उन्हें कुछ कठिन कोड रूट आइटम जैसे कि 0000000-00000-00000-TREE-ROOT-ITEM

var पेड़ = फ्लेटल (रिकॉर्ड, "ट्री-रूट-आईटीईएम");

 function unflatten(records, rootCategoryId, parent, tree){ if(!_.isArray(tree)){ tree = []; _.each(records, function(rec){ if(rec.parentId.indexOf(rootCategoryId)>=0){ // change this line to compare a root id //if(rec.parentId == 0 || rec.parentId == null){ // example for 0 or null var tmp = angular.copy(rec); tmp.children = _.filter(records, function(r){ return r.parentId == tmp.id; }); tree.push(tmp); //console.log(tree); _.each(tmp.children, function(child){ return unflatten(records, rootCategoryId, child, tree); }); } }); } else{ if(parent){ parent.children = _.filter(records, function(r){ return r.parentId == parent.id; }); _.each(parent.children, function(child){ return unflatten(records, rootCategoryId, child, tree); }); } } return tree; } 

मुझे @ विलियमलेंग के शुद्ध जावास्क्रिप्ट समाधान पसंद है, लेकिन कभी-कभी आपको ऑब्जेक्ट के संदर्भ को रखने के लिए मौजूदा सरणी में बदलाव करने की आवश्यकता होती है।

 function listToTree(data, options) { options = options || {}; var ID_KEY = options.idKey || 'id'; var PARENT_KEY = options.parentKey || 'parent'; var CHILDREN_KEY = options.childrenKey || 'children'; var item, id, parentId; var map = {}; for(var i = 0; i < data.length; i++ ) { // make cache if(data[i][ID_KEY]){ map[data[i][ID_KEY]] = data[i]; data[i][CHILDREN_KEY] = []; } } for (var i = 0; i < data.length; i++) { if(data[i][PARENT_KEY]) { // is a child if(map[data[i][PARENT_KEY]]) // for dirty data { map[data[i][PARENT_KEY]][CHILDREN_KEY].push(data[i]); // add child to parent data.splice( i, 1 ); // remove from root i--; // iterator correction } else { data[i][PARENT_KEY] = 0; // clean dirty data } } }; return data; } 

Exapmle: https://jsfiddle.net/kqw1qsf0/17/

 var data = [{"country":"india","gender":"male","type":"lower","class":"X"}, {"country":"china","gender":"female","type":"upper"}, {"country":"india","gender":"female","type":"lower"}, {"country":"india","gender":"female","type":"upper"}]; var seq = ["country","type","gender","class"]; var treeData = createHieArr(data,seq); console.log(treeData) function createHieArr(data,seq){ var hieObj = createHieobj(data,seq,0), hieArr = convertToHieArr(hieObj,"Top Level"); return [{"name": "Top Level", "parent": "null", "children" : hieArr}] function convertToHieArr(eachObj,parent){ var arr = []; for(var i in eachObj){ arr.push({"name":i,"parent":parent,"children":convertToHieArr(eachObj[i],i)}) } return arr; } function createHieobj(data,seq,ind){ var s = seq[ind]; if(s == undefined){ return []; } var childObj = {}; for(var ele of data){ if(ele[s] != undefined){ if(childObj[ele[s]] == undefined){ childObj[ele[s]] = []; } childObj[ele[s]].push(ele); } } ind = ind+1; for(var ch in childObj){ childObj[ch] = createHieobj(childObj[ch],seq,ind) } return childObj; } }