chrisl-921fb74d
chrisl-921fb74d

Reputation: 23100

Convert a string key in a JSON object to a child object?

I've looped through an document.form.element the names are constructed into an array name like so:

Current output

Some of the names of they keys are like so in JSON:

{ 
    data[name]: "foo",
    data[address]: "baz drive",
    data[city]: "Dallas",
    data[state]: "Texas",
    data[phone]: "555-1212"
}

Desired output

Is there a way to convert it to this with Pure JavaScript (and without frameworks like jQuery) without using eval?:

{ 
    data: {
        name: "foo",
        address: "baz drive",
        city: "Dallas",
        state: "Texas",
        phone: "555-1212"
    }
}

What have i tried so far

<script type="javascript">
var o =   { 
    data[name]: "foo",
    data[address]: "baz drive",
    data[city]: "Dallas",
    data[state]: "Texas",
    data[phone]: "555-1212"
}

var temp = [];

for (key in o) {
  temp[JSON.parse(key)] = o;
}
</script>

Fiddle is here: http://jsfiddle.net/chrisjlee/medbzv9a/

Or is this not totally possible?

Upvotes: 0

Views: 166

Answers (2)

Lucas Trzesniewski
Lucas Trzesniewski

Reputation: 51330

The following function should fix the object. It will be executed recursively and it can handle arrays too.

var fixKeys = function(obj) {
    if (typeof(obj) != "object")
        return obj;

    if (Object.prototype.toString.call(obj) == "[object Array]")
        return obj.map(arguments.callee);

    var newObj = {};
    for (var key in obj) {
        if (!obj.hasOwnProperty(key))
            continue;

        var m = /^(\w+)\[(\w+)\]$/.exec(key);
        if (m) {
            newObj[m[1]] = newObj[m[1]] || {};
            newObj[m[1]][m[2]] = arguments.callee(obj[key]);
        } else {
            newObj[key] = arguments.callee(obj[key]);
        }
    }

    return newObj;
};

Fiddle


And here's an even better version, which can handle data of this type:

var o = { 
    "data[name]": "foo",
    "data[address][street]": "baz drive",
    "data[address][city]": "Dallas",
    "data[address][state]": "Texas",
    "data[phone]": "555-1212",
    someArray: [
        {"test[a]": 42},
        42
    ]
};

Just in case you need it:

var fixKeys = function(obj) {
    if (typeof(obj) != "object")
        return obj;

    if (Object.prototype.toString.call(obj) == "[object Array]")
        return obj.map(arguments.callee);

    var newObj = {};
    for (var key in obj) {
        if (!obj.hasOwnProperty(key))
            continue;

        var m = /^(\w+)(?:\[\w+\])+$/.exec(key);
        if (m) {
            var subKey = key.substr(m[1].length);
            var subObj = newObj[m[1]] = newObj[m[1]] || {};

            while (m = /^\[(\w+)\]\[/.exec(subKey)) {
                subObj = subObj[m[1]] = subObj[m[1]] || {};
                subKey = subKey.substr(m[0].length - 1);
            }

            m = /^\[(\w+)\]$/.exec(subKey);
            subObj[m[1]] = arguments.callee(obj[key]);
        } else {
            newObj[key] = arguments.callee(obj[key]);
        }
    }

    return newObj;
};

Fiddle

Upvotes: 1

Mithun Satheesh
Mithun Satheesh

Reputation: 27845

Do like

var o =   { 
    "data[name]": "foo",
    "data[address]": "baz drive",
    "data[city]": "Dallas",
    "data[state]": "Texas",
    "data[phone]": "555-1212"
};
o.data = {};
for (key in o) {
  var index = key.match(/[^[\]]+(?=])/g);
    if(index) {
      o.data[index] = o[key];
      delete(o[key]);
    }
}
console.log(o);

Here is a sample fiddle.

Upvotes: 2

Related Questions