2

我有一堆形式的字符串:“AAA.BBB[0].CCC.DDD[5].EEE = 123”。有些包含更深的嵌套数组。如何将该点表示法转换为等效的 JSON 对象?如果它提供任何额外的优势,我正在使用 jQuery。我已经找到了几乎可以做到这一点的方法,但是当包含数组时没有解决方案有效。

编辑:我需要对许多字符串执行此操作并最终将它们组合起来。特别是这个应该成为表单的对象(假设我没有犯任何错误): { "AAA" : { "BBB": [ "CCC : { "DDD": [ {}, {}, {}, {}, {}, { "EEE": 123 } ] } ] }

4

2 回答 2

3

您所描述的不是可以转换为 JSON 的东西。您所描述的是对象的层次结构,当然,但是在那里有那些大括号,您显然只看到一个更大的对象的一部分。然而,为了让解析器将该字符串转换为 javascript 对象,我们可以这样做:

function splitStringToObject(string){
  var sourceArray = string.split('.');
  var top = {};
  var point = top;
  while (sourceArray.length){
    var work = sourceArray.shift();
    if ( /([a-zA-Z_][a-zA-Z0-9_]*)\[([a-zA-Z0-9_]+)\]/.test(work) ){
      console.log('found match alpha index')
      //found an array identifier with a variable name inside ('bbb[aaa]')
      var matches = /([a-zA-Z_][a-zA-Z0-9_]*)\[([a-zA-Z0-9_]+)\]/.exec(work);
      var matchName = matches[1];
      var matchIndex = matches[2];
      point[matchName] = [];
      point[matchName][matchIndex] = {};
      point = point[matchName][matchIndex];
    } else if ( /([a-zA-Z_][a-zA-Z0-9_]*)\[([0-9]+)\]/.test(work) ) {
      console.log('found match numeric index')
      //found an array identifier with a numeric index inside ('bbb[0]')
      var matches = /([a-zA-Z_][a-zA-Z0-9_]*)\[([a-zA-Z0-9_]+)\]/.exec(work);
      var matchName = matches[1];
      var matchIndex = matches[2];
      point[matchName] = [];
      point[matchName][matchIndex] = {};
      point = point[matchName][matchIndex];
    } else if ( work.indexOf('[') > -1 || work.indexOf(']') > -1 ) {
      console.log('found bad egg with ' + work)
    } else if ( work.indexOf('=') > 0 ) { 
      console.log('found = inside')
      //test for equals sign in the string
      var morework = work.split('=');
      work = morework[0].trim();
      sourceArray.push('='+morework[1])
      point[work] = morework[1].trim();
      point = point[work];
    } else { 
      console.log('found plain word')
      //assume work is aok to use as another object here.
      work = work.trim();
      point[work] = {};
      point = point[work];
    }
  }
  //you may not want this next part
  var ret;
  //let's pull our value off the top, altho if we do this, I don't know
  //how to retain the name. I prefer to return it under top still
  for (var k in top){
    ret = top[k];
  }

  console.log(ret);
  return ret;

  // alternately call
  return top;
}

然而,这只是一个解析器,我们如何使用它呢?好吧,我们需要给它我们的字符串。我将假设您可以将所有字符串整齐地放入一个数组中,如下所示:

var strings = [
  "AAA.BBB[0].CCC.DDD[1].EEE = 123",
  "AAA.BBB[0].CCC.DDD[2].EEE = 123",
  "AAA.BBB[0].CCC.DDD[4].EEE = 123",
  "AAA.BBB[0].CCC.DDD[5].EEE = 123",
];

然后下一部分变得非常简单,正如我们在这里看到的:

var objectsConverted = [];
for(var k in strings){
  objectsConverted[k] = splitStringToObject(strings[k]);
}

var result = {};
for(var k in objectsConverted){
  jQuery.extend(true,result,objectsConverted[k]);
}

console.log(result);

最后,如果我 JSON.stringify(result) 我得到:

"{"BBB":[{"CCC":{"DDD":[null,{"EEE":"123"},{"EEE":"123"},null,{"EEE":"123"},{"EEE":"123"}]}}]}"

请阅读函数末尾的警告,名称空间因返回方法的选择而丢失(我从顶部返回而不是嵌套一次)

于 2012-06-19T22:26:30.253 回答
0

AAA.BBB[0].CCC.DDD[5].EEE

变成:

{AAA : {
  BBB : [{ 
   CCC: {
    DDD: [ 
...

如果您有一个成员X[Y],您只需将其转换为映射X到元素数组的对象。

这有帮助吗?

于 2012-06-19T21:38:21.333 回答