Reputation: 23544
I have an object with named keys like this
{
'name[first]': 'john',
'name[last]': 'doe'
}
that I want to convert to:
{
'name' : {
'first' : 'john',
'last' : 'doe'
}
}
Any idea on an elegent way to do this?
Upvotes: 1
Views: 169
Reputation: 22682
You can try the following:
var obj = {
'name[first]': 'john',
'name[last]': 'doe'
}
var result = Object.keys(obj).reduce(function(newObj, prop) {
var key = prop.split(/\[|\]/)[1];
newObj[key] = obj[prop];
return newObj;
}, {})
console.log(result);
Upvotes: 0
Reputation: 122047
You can use reduce()
to return obj and regular expression to split key.
var obj = {
'name[first]': 'john',
'name[last]': 'doe'
}
var result = Object.keys(obj).reduce(function(r, e) {
var key = e.split(/\[(.*?)\]/)
if (!r[key[0]]) r[key[0]] = {}
r[key[0]][key[1]] = obj[e]
return r;
}, {})
console.log(result)
For nested key structure you could again use reduce but with different approach to keys but then you face problem of deep merge
of object and for that you can use lodash.
var obj = {
'name[first[foo]]': 'john',
'name[last]': 'doe',
'name[last[foo[bar]]]': 'doe'
}
var result = Object.keys(obj).reduce(function(r, e) {
var key = e.replace(/\[/g, '.').replace(/\]/g, '').split('.')
var o = {}
key.reduce(function(re, el, i) {
return i != key.length - 1 ? re[el] = {} : re[el] = obj[e]
}, o)
r = _.merge(r, o)
return r;
}, {})
console.log(JSON.stringify(result, 0, 4))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
Upvotes: 4
Reputation: 8193
var obj = {
'name[first]': 'john',
'name[last]': 'doe'
}
var newObj = {};
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
var keys = property.match(/(\w+)/g);
if (keys && keys.length == 2) {
newObj[keys[0]] = newObj[keys[0]] || {};
newObj[keys[0]][keys[1]] = obj[property];
}
}
}
console.log(newObj);
Upvotes: 0
Reputation: 92854
The solution using Object.keys
, Array.prototytpe.reduce
and String.prototype.match
functions:
var obj = {'name[first]': 'john', 'name[last]': 'doe'};
var result = Object.keys(obj).reduce(function (o, key) {
var parts = key.match(/^(\w+)\[(\w+)\]$/);
if (!o[parts[1]]) {
o[parts[1]] = {};
}
o[parts[1]][parts[2]] = obj[key];
return o;
}, {});
console.log(result);
Upvotes: 0
Reputation: 9690
Using a for..in
loop and constructing a new object:
var obj = {
'name[first]': 'john',
'name[last]': 'doe'
};
var newObj = {}
for (var key in obj) {
var parts = key.split(/\[|\]/);
if(!newObj.hasOwnProperty(parts[0]))
newObj[parts[0]] = {};
newObj[parts[0]][parts[1]] = obj[key];
}
console.log(newObj);
Upvotes: 1