Я на самом деле хочу преобразовать строку в глубокий объект, но я уверен, что преобразование строки в массив - это первый шаг. Позволь мне объяснить.

Я использую 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));
1
user1032531 11 Апр 2019 в 17:31

2 ответа

Лучший ответ

Вы можете перебрать данные ключи и присвоить значение, взяв последний ключ.

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);
3
Nina Scholz 11 Апр 2019 в 14:57

Как насчет этого:

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}}}

2
dbramwell 11 Апр 2019 в 14:56