遍历JSON对象以构建JSTree

时间:2016-10-12 12:17:40

标签: javascript json jstree traversal

我有一个JSON对象,想要遍历它以便它匹配JSTree的结构:

原创JSON:



{
	"analogBasebandProcessorBoardType": "Test_BOARD",
	"tuners": {
		"tuner1": "RFE_MAIN",
		"tuner2": "MAX93"
	},
	"allowedSoftConfigs": ["30-16", "30-29", "10-22"]
}




应该如下所示:



{
    'core': {
      'data': [
      {
          'text': 'analogBasebandProcessorBoardType',
          'children': 
                      [
                        {
                          'text': 'Test_BOARD'
                        }
                      ]
      }, 
      {
          'text': 'tuners',
          'children': 
                      [{
                        'text': 'Tuner1',
                        'children': 
                        [{
                          'text': 'RFE_MAIN'
                        }]
                      },
                       {
                         'text': 'Tuner2',
                         'children': 
                         [{
                           'text': 'MAX93'
                         }]
                       }
                      ]
       },

       {
          'text': 'allowedSoftConfigs',
          'children': 
          						[
                        {
                            'text': '30-16'
                         }, 
                         {
                            'text': '30-29'
                         },
                         {
                            'text': '10-22'
                         }
							         ]
        },

      ]
    }
  }




我认为解决这个问题的唯一方法就是遍历。我试过了,但这不是我想要的,但我想我离解决方案的距离不是很远。

这是正在生成的JSON:



{
	"core": {
		"data": {
			"analogBasebandProcessorBoardType": {
				"text": "analogBasebandProcessorBoardType",
				"children": [{
					"text": "Test_BOARD"
				}],
				"tuners": {
					"tuner1": {
						"text": "tuner1",
						"children": [{
							"text": "RFE_MAIN"
						}],
						"tuner2": {
							"text": "tuner2",
							"children": [{
								"text": "MAX93"
							}],
							"allowedSoftConfigs": {
								"0": {
									"1": {
										"2": {
											"text": "2",
											"children": [{
												"text": "10-22"
											}]
										},
										"text": "1",
										"children": [{
											"text": "30-29"
										}]
									},
									"text": "0",
									"children": [{
										"text": "30-16"
									}]
								}
							}
						}
					}
				}
			}
		}
	}
}




我的代码总是使用" name"作为数据阵列的关键。如果没有钥匙,这是正确的。但我不确定这种行为是在哪里造成的。

如果有人可以看一眼就好了,因为我不知道如何解决它。 这是完整的代码,但我认为在jsfiddle中更容易查看:



//function to add something to objects with a string path
function assign(obj, prop, value) {
    if (typeof prop === "string")
        prop = prop.split(".");

    if (prop.length > 1) {
        var e = prop.shift();
        assign(obj[e] =
                 Object.prototype.toString.call(obj[e]) === "[object Object]"
                 ? obj[e]
                 : {},
               prop,
               value);
    } else
        obj[prop[0]] = value;
}



$(function() {
  // 6 create an instance when the DOM is ready

var tbjsonstring = '{	"analogBasebandProcessorBoardType": "Test_BOARD",	"tuners": {		"tuner1": "RFE_MAIN","tuner2": "MAX93"	},	"allowedSoftConfigs": ["30-16", "30-29", "10-22"]}';

var tbjson = JSON.parse(tbjsonstring);

var computedJSON = {
    'core': {
      'data': [
      ]
    }
  }
var path = "core.data";

console.log(tbjson);
(function traverse(o) {
var z = 0;
    for (var i in o) {
      data0 = {
                  'text': i,
             }
       data1 = {
                  'text': o[i],
             }      
      if(traversed == 1){
      console.log("traversed" + o[i]);
      //	assign(computedJSON,path,data1);
        traversed = 0;
      }else{
     //   assign(computedJSON,path,data0);
      }       
     
      console.log('key : ' + i + ', value: ' + o[i]);

			//console.log(path);
			path = path+"."+i;
      z++;
      if (o[i] !== null && typeof(o[i])=="object") {
        //going on step down in the object tree!!
        var traversed = "1";
        traverse(o[i]);
      }else{
      //key value pair, no children
      data = {};
      data = {
          'text': i,
          'children': [{
            'text': o[i]
          }]
      }
      assign(computedJSON,path,data);
      }  
    }
  })
  (tbjson);

//print to the console
console.log(JSON.stringify(computedJSON));





//This is the working json, computedJSON should looke like this:
  var jstreejson = {
    'core': {
      'data': [
      {
          'text': 'analogBasebandProcessorBoardType',
          'children': 
                      [
                        {
                          'text': 'Test_BOARD'
                        }
                      ]
      }, 
      {
          'text': 'tuners',
          'children': 
                      [{
                        'text': 'Tuner1',
                        'children': 
                        [{
                          'text': 'RFE_MAIN'
                        }]
                      },
                       {
                         'text': 'Tuner2',
                         'children': 
                         [{
                           'text': 'MAX93'
                         }]
                       }
                      ]
       },

       {
          'text': 'allowedSoftConfigs',
          'children': 
          						[
                        {
                            'text': '30-16'
                         }, 
                         {
                            'text': '30-29'
                         },
                         {
                            'text': '10-22'
                         }
							         ]
        },

      ]
    }
  }


//jstree initialization
  $('#jstree').jstree(jstreejson);
  $('#tbjstree').jstree(computedJSON);
  // 7 bind to events triggered on the tree
  $('#jstree').on("changed.jstree", function(e, data) {
    console.log(data.selected);
  });

});

The won't run in the stackoverflow-snippet-editor (even with loaded js/css files) so please visit jsfiddle for a working demo:
<a href='https://jsfiddle.net/dnffx4g8/6/' target='_blank'>JSFiddle Demo</a>
&#13;
&#13;
&#13;

jsfiddle-link: https://jsfiddle.net/dnffx4g8/6/

2 个答案:

答案 0 :(得分:1)

您可以使用迭代递归方法,使用函数检查数组和对象并相应地进行迭代。

function buildObject(source) {
    if (Array.isArray(source)) {
        return source.reduce(function (r, a) {
            if (a !== null && typeof a === 'object') {
                return r.concat(buildObject(a));
            }
            r.push({ text: a });
            return r;
        }, []);
    }
    if (source !== null && typeof source === 'object') {
        return Object.keys(source).map(function (k) {
            return {
                text: k,
                children: buildObject(source[k])
            };
        });
    }
    return [{ text: source }];
}

var data = { "analogBasebandProcessorBoardType": "Test_BOARD", "tuners": { "tuner1": "RFE_MAIN", "tuner2": "MAX93" }, "allowedSoftConfigs": ["30-16", "30-29", "10-22"], "PathValue": [{ "links": ["in1->GSES_1.in1", "GSES_1.out1->GSES_1.in1", "GSES_1.out1->out1_1"], "ParamFile": "IN1_OUT12.txt" }, { "links": ["in1->GSES_1.in1", "GSES_1.out2->GSES_2.in1", "GSES_2.out1->out1_2"], "ParamFile": "IN1_OUT52.txt" }] },
    result = { core: { data: buildObject(data) } };

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

ES6

function buildObject(source) {
    if (Array.isArray(source)) {
        return source.map(text => ({ text }));
    }
    if (source !== null && typeof source === 'object') {
        return Object.keys(source).map(text => ({ text, children: buildObject(source[text])}));
    }
    return [{ text: source }];
}

var object = { analogBasebandProcessorBoardType: "Test_BOARD", tuners: { tuner1: "RFE_MAIN", tuner2: "MAX93" }, allowedSoftConfigs: ["30-16", "30-29", "10-22"] },
    result = { core: { data: buildObject(object) } };
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)

给定名为 data 的对象,您可以使用此ES6函数:

var result = {
  core: {
    data: (function treeify(data) {
        return Array.isArray(data) ? data.map ( value => treeify(value) )
            : typeof data !== 'object' || data == null ? { text: data }
            : Object.keys(data).map(key => ({ text:key, children: [treeify(data[key])] }));
    })(data)
  }
};

以下是包含示例数据的代码段:

var data = {
	"analogBasebandProcessorBoardType": "Test_BOARD",
	"tuners": {
		"tuner1": "RFE_MAIN",
		"tuner2": "MAX93"
	},
	"allowedSoftConfigs": ["30-16", "30-29", "10-22"]
};

var result = {
  core: {
    data: (function treeify(data) {
        return Array.isArray(data) ? data.map ( value => treeify(value) )
            : typeof data !== 'object' || data == null ? { text: data }
            : Object.keys(data).map ( key => ({ text: key, children: [treeify(data[key])] }) );
    })(data)
  }
};

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

注意:我不会将您的对象命名为 tbjson computedJson ,以避免与纯JavaScript对象混淆。术语JSON最好保留用于文本符号。

代码说明

treeify 是一个递归函数。它返回的值取决于传递给它的参数的数据类型:

  • 当它是一个数组(Array.isArray())时,为每个元素(treeify(value))递归调用该函数,并将这些结果汇编在一个新数组中(返回值为{ {1}})返回给调用者。

  • 当它是非对象时(因为data.map()被认为是一个对象需要单独的测试),那么该值将赋予新对象的null属性返回给调用者(text)。

  • 当它是一个对象时,该对象的键被迭代({ text: data }),并且对于每个对应的值,该函数被递归地调用(Object.keys(data).map())。该结果放在一个数组中并分配给新对象的treeify(data[key])属性,而该键被分配给该同一对象的children属性。这将返回给调用者。

结果变量将启动调用链以初始化text属性的值。