简体   繁体   中英

Most elegant way to create a JSON Object

I hava a javacript object that look like this.

val = 
{
default: "version1"
version1: "abc.com"
version2: "def.com"
...
versionn:"xyz.com"
}

I want to convert this to a nested json like this

"newval": {
"website": {
    "url": "abc.com"
},
"versions": {
    "version1": {
        "website": {
            "url": "abc.com"
        }
    },
    "version2": {
        "website": {
            "url": "def.com"
        }
    }
}

}

My version uses a lot if if statements and unnecessary variables. Is there an elegant way to convert/create this JSON.

ie the default version is the one that comes under newval.website and all the version data is the value fir newval.website.versions

Setting the .website property is pretty simple. Just a matter of looking up the key that default holds.

The other part can be done by filtering out the default key, and then mapping the remaining ones to a new list of objects that are assigned to the result using Object.assign .

 var val = { default: "version1", version1: "abc.com", version2: "def.com", version3:"xyz.com" }; var res = { website: {url: val[val.default]}, versions: Object.assign( ...Object.keys(val) .filter(k => k !== "default") .map(k => ({[k]: {website: {url: val[k]} } })) )}; console.log(res); 


Here's another way that avoids needing the .filter() . It assumes you don't mind making default non-enumerable on the original object.

 var val = { default: "version1", version1: "abc.com", version2: "def.com", version3:"xyz.com" }; var res = { website: {url: val[Object.defineProperty(val, "default", {enumerable:false}).default]}, versions: Object.assign( ...Object.keys(val).map(k => ({[k]: {website: {url: val[k]} } })) )}; console.log(res); 

The property is still configurable, so you could reset it if desired.


Or using .entries() instead of .keys() with parameter destructuring in the .map() callback.

 var val = { default: "version1", version1: "abc.com", version2: "def.com", version3:"xyz.com" }; var res = { website: {url: val[Object.defineProperty(val, "default", {enumerable:false}).default]}, versions: Object.assign( ...Object.entries(val).map(([k, v]) => ({[k]: {website: {url: v} } })) )}; console.log(res); 

My version:

var val = {
  default: 'version1',
  version1: 'abc.com',
  version2: 'def.com',
  version3: 'xyz.com'
}

var res = {
  website: {url: val[val.default]},
  versions: Object.entries(val).reduce(function(a, [k, v]) {
    if (k != 'default') a[k] = {website: {url: v}}
    return a
  }, {})
}

console.log(res)

And here's my version, just reducing the entries directly into the websites property, excluding the default property

 var val = { default: "version1", version1: "abc.com", version2: "def.com", versionn: "xyz.com" } var result = { newval : {website : val.default}, versions : Object.entries(val).reduce((a,b)=>((b[0] != 'default'?a[b[0]]={website:b[1]}:0),a),{}) }; console.log(result) 

You could assign the part for default directly and the rest by iterating the keys and assigning to the object.

 var values = { default: "version1", version1: "abc.com", version2: "def.com", versionn: "xyz.com" }, result = { newval: { website: { url: values[values.default] }, versions: Object.assign(...Object.keys(values).map(k => k === 'default' ? {} : { [k]: { website: { url: values[k] } } })) } }; console.log(result); 
 .as-console-wrapper { max-height: 100% !important; top: 0; } 

A bit more efficient and compatible without function call:

 val = { default:"version1", version1:"abc.com", version2:"def.com", versionn:"xyz.com" } newval = { website: { url: val[val.default] }, versions: { } } for (k in val) if (k !== 'default') newval.versions[k] = { website: { url: val[k] } } console.log({newval}) 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM