遍历JSON个对象构建JSTree

Traverse JSON object to build JSTree

我有一个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 Whosebug-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>

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

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

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

给定一个名为 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; }

注意:我不会将您的对象命名为 tbjsoncomputedJson,以避免与普通的 JavaScript 对象混淆。术语 JSON 最好保留用于文本表示法。

代码解释

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

  • 当是数组时(Array.isArray())则对每个元素递归调用函数(treeify(value)),并将这些结果组装到一个新的数组中( return data.map()) 的值 returned 给调用者。

  • 当它是一个非对象时(因为 null 被认为是一个对象,因此需要单独的测试),然后将值赋予 text 属性 一个新对象的 returned 给调用者 ({ text: data }).

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

结果变量将启动用于初始化 data 属性.

值的调用链