最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Javascript, how to split key with dot to recovery json structure - Stack Overflow

programmeradmin6浏览0评论

I have a json, it is

{ 
  "prop1.sub1.sub2": "content1",
  "prop1.sub1.sub3": "content2",
  "prop2.sub1.sub2": "content3",
  "prop3.sub1.sub2": "content4"
}

I want to recovery the structure, like

{ 
  "prop1": {
    "sub1": {
      "sub2" : "content1",
      "sub3" : "content2"
    }
  },
  "prop2": {
    "sub1": {
      "sub2" : "content3"
    }
  },
  "prop3": {
    "sub1": {
      "sub2" : "content4"
    }
  }
}

I split the key with dot to get each key.

for (var key in json) {
  var keySplit = key.split('.');
  // Todo: recovery the structure
}

But not found a good solution.

Is anyone has solution?

I have a json, it is

{ 
  "prop1.sub1.sub2": "content1",
  "prop1.sub1.sub3": "content2",
  "prop2.sub1.sub2": "content3",
  "prop3.sub1.sub2": "content4"
}

I want to recovery the structure, like

{ 
  "prop1": {
    "sub1": {
      "sub2" : "content1",
      "sub3" : "content2"
    }
  },
  "prop2": {
    "sub1": {
      "sub2" : "content3"
    }
  },
  "prop3": {
    "sub1": {
      "sub2" : "content4"
    }
  }
}

I split the key with dot to get each key.

for (var key in json) {
  var keySplit = key.split('.');
  // Todo: recovery the structure
}

But not found a good solution.

Is anyone has solution?

Share Improve this question asked Oct 5, 2016 at 5:24 Peace PanPeace Pan 3934 silver badges15 bronze badges 3
  • 1 Todo: recovery the structure - have you tried anything - you're on the right path – Jaromanda X Commented Oct 5, 2016 at 5:25
  • Why does prop1.sub1 contain both sub2 and sub3 properties? – guest271314 Commented Oct 5, 2016 at 5:27
  • because it's the question – Jaromanda X Commented Oct 5, 2016 at 5:34
Add a ment  | 

2 Answers 2

Reset to default 9

You can use Array#reduce method.

var obj = {
  "prop1.sub1.sub2": "content1",
  "prop1.sub1.sub3": "content2",
  "prop2.sub1.sub2": "content3",
  "prop3.sub1.sub2": "content4"
};

// iterate over the property names
Object.keys(obj).forEach(function(k) {
  // slip the property value based on `.`
  var prop = k.split('.');
  // get the last value fom array
  var last = prop.pop();
  // iterate over the remaining array value 
  // and define the object if not already defined
  prop.reduce(function(o, key) {
    // define the object if not defined and return
    return o[key] = o[key] || {};
    // set initial value as object
    // and set the property value
  }, obj)[last] = obj[k];
  // delete the original property from object
  delete obj[k];
});

console.log(obj);

Answer by Pranav C Balan is right for the question you asked. But JSON's might not be as simple as you have mentioned above and can have array's also and few keys might not have "." in them. To handle all these cases you can use the following one.

var obj = {
  "prop1.sub1.sub2": "content1",
  "prop1.sub1.sub3": "content2",
  "prop2.sub1.sub2": "content3",
  "prop3.0.sub2": "content4"
};

function createJSONStructure(obj) {
    Object.keys(obj).forEach(function(k) {
        var prop = k.split('.'); //split on . to get elements 
        if(prop.length >1){ //If there is no dot just key the value as is.
            let data = obj;//Copy the default object to data in each loop 
            for(i=0;i<prop.length-1;i++){
                if(data[prop[i]]){ // Check if the key exists 
                    if((prop[i+1].match(/^\d+$/) && !Array.isArray(data[prop[i]])) // Check if the next key is a digit and the object we have is a JSON
                        || (!prop[i+1].match(/^\d+$/) && Array.isArray(data[prop[i]]))){ // Check if the next key is not a digit and the object we have is a Array
                            throw new Error("Invalid header data"); //If any of the above cases satisfy we cannot add the key so we can throw an error.
                    }
                    data  = data[prop[i]]; // If key exisits make the data variable as the value of the key
                }else {
                    if(prop[i+1].match(/^\d+$/)){ //If the key is not available see if the next parameter is a digit or string to decide if its array or string
                        data[prop[i]]  =  [];
                    }else{
                        data[prop[i]]  =  {};
                    }
                    data = data[prop[i]];  //Assign this new object to data
                }
                
            };
            data[prop[i]] = obj[k];  //Finally add the value to final key 
            delete obj[k]; // delete the exisiting key value
        }
      });
    return obj;
}

console.log(createJSONStructure(obj));

发布评论

评论列表(0)

  1. 暂无评论