如何将JavaScript数组(或定界字符串)转换为带有子对象的对象

时间:2019-04-11 14:31:25

标签: javascript

我实际上希望将字符串转换为深层对象,但可以肯定的是,将字符串转换为数组是第一步。让我解释一下。

我正在使用xeditable,默认情况下,它将{"name": "somePropertyName", "value": "someValue"}发送到服务器,但是,我希望发送{"somePropertyName": "someValue"}。我可以通过将$.fn.editable.defaults.params设置为适当的回调来完成此操作。

现在我卡住的部分。我正在使用一种特殊的命名模式,如果名称中包含句点(即名称为a.b.c),我不想将{"a.b.c": "someValue"}发送到服务器,而是发送{"a":{"b":{"c":"someValue"}}}到服务器。

我有一个部分正常工作的版本,但是,它不是很优雅,更重要的是,我没有使最后一个属性正常工作,并且暂时对其进行了硬编码,这是不可接受的。

这怎么实现?

$.fn.editable.defaults.params = function(params){
    return nvp2obj(params.name, params.value);
}

function nvp2obj(n, v, d) {
    d = d ? d : '.';
    n = n.split('.');
    var o = {};
    var r = o;
    n.reduce(function(total, currentValue, currentIndex, arr) {
        if(r) {
            r[currentValue]={};
            r=o[currentValue];
        }
        else {
            //this is obviously not correct
            o.a.b.c=v;
        }
        return o;
        }, o);
    return o;
}
var test = nvp2obj('a.b.c', 'someValue'); //{"a":{"b":{"c":"someValue"}}}
console.log('test', JSON.stringify(test));

2 个答案:

答案 0 :(得分:3)

您可以迭代给定的键并通过获取最后一个键来分配值。

function setValue(object, keys, value) {
    var last = keys.pop();
        
    keys.reduce((o, k) => o[k] = o[k] || {}, object)[last] = value;
}

var test = {};
    
setValue(test, 'a.b.c'.split('.'), 'someValue');
setValue(test, 'a.d.e'.split('.'), 'someValue2');
setValue(test, 'a.b.a'.split('.'), 'someValue3');

console.log(test);

答案 1 :(得分:2)

如何?

function nvp2obj(n, v, d) {
  n = n.split(d || '.');
  n.reverse()
  return n.reduce(function(res, it) {
    return {[it]: res}
  }, v)
}


var test = nvp2obj('a.b.c', 'someValue');
console.log('test', JSON.stringify(test));

test = nvp2obj('a|b|c', 'someValue', '|');
console.log('test', JSON.stringify(test));

从头开始遍历键(以'c'开头),首先返回一个对象,最后一个键对应于所需的值({c: value})。然后是{b: {c: value}},然后是{a: {b: {c: value}}}