我实际上希望将字符串转换为深层对象,但可以肯定的是,将字符串转换为数组是第一步。让我解释一下。
我正在使用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));
答案 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}}}