preface

Recently I saw a lot of articles about flat array to tree structure on the nuggets, are all kinds of, in real work, I also had a similar scene, but a little more bizarre ~

background

I am a visual development platform and a low-code development tool for quickly realizing visual pages (PC, mobile phone, physical large screen) based on drag and drop. In the subsequent iterations of development, I encountered such a problem:

PC page has been developed about 40% of the progress, the customer’s new demand, can a set of code compatible with the mobile end? Oh, my god! It’s a new need, but it’s an imperative. It’s a must! As the main developer of tool platform research and development, the result is, of course, silently “dry”, because the platform itself is by dragging drag generate configuration files, and then rely on the platform, the dynamically generated page, in the configuration file layout configuration parameters, certainly to start from here (layout parameters structure change), well, the farther the distance, the theme, Please check my other article visual platform implementation ideas

Layout parameter structure

[{
	"x": 1.// the X-axis position
	"y": 1.// Y position
	"w": 35.// Width ratio
	"h": 24.// High ratio
	"i": "1"./ / the only value
	"title": "Heading 1"  / / title
}, {
	"x": 2."y": 6."w": 19."h": 17."i": "2"."title": "Heading 2"}... Unknown quantity];Copy the code

A common ArrayToTree case

 let data = [
          {"parent_id": 0."id":1."value": "Heading 1"},
          {"parent_id": 1."id":3."value": "Heading 2"},
          {"parent_id": 4."id":6."value": "Title"},
          {"parent_id": 3."id":5."value": "Title 4"},
          {"parent_id": 2."id":4."value": "Title 5"},
          {"parent_id": 1."id":2."value": Title "6"},]1 / / way
function ArrayToTree(data){
    let result = []
    
    let dg_fun = (item) = > {
         let children = []
         data.forEach((n,index) = > {
            if(n.parent_id == item.id){
                children.push(n)
                data.splice(index,1)
                item["children"] = children
                if(data.length) dg_fun(n)
            }
        })
       
    }

    data.forEach((c,index) = > {
        if(c.parent_id == 0){
            result.push(c)
            data.splice(index,1)
            dg_fun(c)
        }
    })

    return result;
}


2 / / way
function toTree(data) {
  data.forEach(item= > {
      delete item.children;
  })

  const map = {};
  data.forEach(item= > {
      map[item.id] = item;
  })

  const list = [];
  data.forEach(item= > {
      let parent = map[item.parent_id];
      if (parent) {
          (parent.children || (parent.children = [])).push(item);
      } else {
          list.push(item)
      }
  })
  return list;
}
      
      
Copy the code

The above two methods, I will not introduce more

  • Method 1 is to find the top node recursively, and then pass in a recursive method, recursively find the child nodes in turn, and then record and remove them until data.length = 0
  • Method 2, which is slightly better, establishes the mapping table, traverses it once, goes directly to the parent node, finds the corresponding parent node and pushes itself into the children of the parent node

My actual case

Describe it through a previous test development view

As is shown in

  • The yellow box on the left is a tree of components used on the current pageSo here's what the flat array looks like when it goes to tree
  • The green boxes on the left are the root nodes of the tree, each containing its own child nodes
  • The red box on the right is the component view. In combination with the tree structure, blocks 1, 2, 3 and 4 correspond to 1, 2, 3 and 4 of the component management in the left column respectively. The largest component element in each block is the current root node element

The goal is to make Pc pages compatible for viewing on mobile phones, and I won’t go into much more detail, but I’ll share ArrayToTree here

The conversion process

In fact, my flat array does not have the default parameters of parent and child level, so I need to use the four parameters x,y, W and H to determine which node is whose parent node and which node is whose child node, so it may be a little difficult to determine

Without more words, directly on the code, write to write can only be written like this, such as children shoes have a good way, the comment section to ridicule, I good optimization optimization


window.Nt_tree_left_data = [{ "x": 0."y": 0."w": 10000."h": 10000 }];

const FormatLeftMenuFun = function (s_copy) {
	var s = JSON.parse(JSON.stringify(s_copy));
	var max = [];
	for (var j = 0; j < s.length; j++) {
		var a = s[j];
		var isMax = true;
		// If a is in b, it is not the outermost rectangle
		for (var i = 0; i < s.length; i++) {
			if (i == j) {
				continue;
			}
			var b = s[i];
			if((a.x >= b.x && a.y >= b.y && a.x + a.w <= b.x + b.w && a.y + a.h <= b.y + b.h) && ! (a.x == b.x && a.y == b.y && a.w == b.w && a.h == b.h)) { isMax =false;
				break; }}// is the outermost element of the array. Insert a into the tree node
		if (isMax) {
			// Record the rectangle to be deleted
			max.push(j);
			// Append a to a node in the tree
			insertNode2Tree(a, Nt_tree_left_data[0]); }}var b2 = [];
	// Build a new array
	for (var j = 0; j < s.length; j++) {
		// Not removed
		if (max.indexOf(j) < 0) { b2.push(s[j]); }}if (b2.length > 0) {
		FormatLeftMenuFun(b2);
	}

	return Nt_tree_left_data;
}

function insertNode2Tree (a, b) {
	// A is in the b box
	if((a.x >= b.x && a.y >= b.y && a.x + a.w <= b.x + b.w && a.y + a.h <= b.y + b.h) && ! (a.x == b.x && a.y == b.y && a.w == b.w && a.h == b.h)) {// Check if b has a subset
		for (var j = 0; b.children && j < b.children.length; j++) {
			if (insertNode2Tree(a, b.children[j])) {
				return true;
			}
		}
		b.children = b.children ? b.children : [];
		b.children.push(a);
		return true;
	}
	return false;
}

export { FormatLeftMenuFun };

Copy the code

The test data

// The above method is needed
var s1=[{"x":1."y":1."w":35."h":24."i":"1"."moved":false."title":"Heading 1"}, {"x":2."y":6."w":19."h":17."i":"2"."moved":false."title":"Heading 2"}, {"x":37."y":1."w":22."h":24."i":"3"."moved":false."title":"Title"}, {"x":3."y":7."w":4."h":2."i":"4"."moved":false."title":"Title 4"}, {"x":22."y":15."w":12."h":8."i":"5"."moved":false."title":"Title 5"}, {"x":22."y":6."w":12."h":8."i":"6"."moved":false."title":Title "6"}, {"x":2."y":2."w":10."h":3."i":"Seven"."moved":false."title":"Title 7"}, {"x":38."y":5."w":21."h":19."i":"8"."moved":false."title":"Title 8"}, {"x":38."y":2."w":6."h":3."i":"9"."moved":false."title":"Title 9"}, {"x":3."y":9."w":7."h":3."i":10."moved":false."title":"Title 10"}, {"x":14."y":7."w":6."h":2."i":11."moved":false."title":11 "title"}, {"x":3."y":15."w":3."h":2."i":12."moved":false."title":"Title 12"}, {"x":3."y":18."w":4."h":2."i":13."moved":false."title":"Title 13"}, {"x":9."y":15."w":3."h":2."i":14."moved":false."title":"Title 14"}, {"x":15."y":15."w":3."h":2."i":15."moved":false."title":"Title 15"}, {"x":7."y":15."w":1."h":5."i":16."moved":false."title":"Title 16"}, {"x":13."y":15."w":1."h":5."i":17."moved":false."title":"Title 17"}, {"x":9."y":18."w":4."h":2."i":18."moved":false."title":"Title 18"}, {"x":1."y":27."w":24."h":24."i":19."moved":false."title":"Title 19"}, {"x":26."y":27."w":16."h":24."i":20."moved":false."title":"Title 20"}, {"x":43."y":27."w":16."h":24."i":21."moved":false."title":"The title 21"}, {"x":2."y":28."w":6."h":3."i":22."moved":false."title":"The title 22"}, {"x":12."y":28."w":13."h":2."i":23."moved":false."title":23 "title"}, {"x":2."y":31."w":23."h":19."i":24."moved":false."title":"Title 24"}, {"x":27."y":28."w":7."h":3."i":25."moved":false."title":"Title 25"}, {"x":44."y":32."w":7."h":17."i":26."moved":false."title":"Title 26"}, {"x":44."y":28."w":7."h":3."i":27."moved":false."title":"Title 27"}, {"x":35."y":32."w":6."h":17."i":28."moved":false."title":"Title 28"}, {"x":36."y":35."w":4."h":2."i":29."moved":false."title":"Title 29"}, {"x":36."y":37."w":5."h":2."i":30."moved":false."title":"Title 30"}, {"x":27."y":32."w":7."h":17."i":31."moved":false."title":"Title 31"}, {"x":36."y":41."w":4."h":2."i":32."moved":false."title":"Title 32"}, {"x":36."y":43."w":5."h":2."i":33."moved":false."title":33 "title"}, {"x":52."y":32."w":6."h":17."i":34."moved":false."title":"Title 34"}, {"x":53."y":35."w":4."h":2."i":35."moved":false."title":"Title 35"}, {"x":53."y":41."w":4."h":2."i":36."moved":false."title":"Title 36"}, {"x":53."y":43."w":5."h":2."i":37."moved":false."title":"Heading 37"}, {"x":53."y":37."w":5."h":2."i":39."moved":false."title":"Title 39"}, {"x":1."y":53."w":18."h":24."i":40."moved":false."title":"Title 40"}, {"x":2."y":54."w":7."h":3."i":41."moved":false."title":"Title" 41}, {"x":20."y":53."w":39."h":24."i":42."moved":false."title":42 "title"}, {"x":4."y":58."w":13."h":18."i":43."moved":false."title":"Title 43"}, {"x":21."y":54."w":9."h":3."i":44."moved":false."title":44 "title"}, {"x":12."y":54."w":6."h":3."i":45."moved":false."title":"Title 45"}, {"x":21."y":57."w":30."h":19."i":46."moved":false."title":"Title 46"}, {"x":52."y":57."w":6."h":19."i":47."moved":false."title":"Title 47"}, {"x":53."y":63."w":5."h":2."i":48."moved":false."title":"Title 48"}, {"x":53."y":61."w":4."h":2."i":49."moved":false."title":"Title 49"}, {"x":53."y":67."w":4."h":2."i":50."moved":false."title":"Title of 50"}, {"x":53."y":69."w":5."h":2."i":51."moved":false."title":Title "51"}, {"x":1."y":79."w":58."h":24."i":52."moved":false."title":"Title 52"}, {"x":2."y":80."w":7."h":3."i":53."moved":false."title":53 "title"}, {"x":2."y":84."w":46."h":7."i":54."moved":false."title":"Title" 54}, {"x":49."y":84."w":9."h":15."i":55."moved":false."title":"Title of 55"}, {"x":2."y":91."w":22."h":8."i":56."moved":false."title":"Title 56"}, {"x":26."y":91."w":22."h":8."i":57."moved":false."title":"Title 57"}, {"x":50."y":87."w":4."h":2."i":58."moved":false."title":"Title 58"}, {"x":50."y":85."w":4."h":2."i":59."moved":false."title":"Title 59"}, {"x":52."y":89."w":3."h":6."i":60."moved":false."title":Title "60"}, {"x":23."y":7."w":4."h":2."i":61."moved":false."title":Title "61"}, {"x":23."y":16."w":4."h":2."i":62."moved":false."title":Title "62"}, {"x":28."y":11."w":4."h":2."i":63."moved":false."title":Title "63"}, {"x":23."y":11."w":4."h":2."i":64."moved":false."title":Title "64"}, {"x":28."y":9."w":4."h":2."i":65."moved":false."title":Title "65"}, {"x":28."y":7."w":4."h":2."i":66."moved":false."title":Title "66"}, {"x":28."y":20."w":4."h":2."i":67."moved":false."title":Title "67"}, {"x":15."y":18."w":4."h":2."i":68."moved":false."title":Title "68"}, {"x":28."y":18."w":4."h":2."i":69."moved":false."title":Title "69"}, {"x":23."y":18."w":4."h":4."i":70."moved":false."title":Title "70"}, {"x":28."y":16."w":4."h":2."i":71."moved":false."title":Title "71"}, {"x":1."y":105."w":58."h":49."i":72."moved":false."title":Title "72"}, {"x":2."y":107."w":9."h":3."i":73."moved":false."title":Title "73"}, {"x":2."y":110."w":5."h":2."i":74."moved":false."title":Title "74"}, {"x":2."y":112."w":57."h":42."i":75."moved":false."title":Title "75"}, {"x":26."y":2."w":4."h":4."i":76."moved":false."title":Title "76"}];
Copy the code

Small encouragement, great growth, welcome to praise, collection