2016-11-13 3 views
1

У меня есть объект, содержащий preformated имена атрибутов сериализованная HTMLFormElement (2-мерная):Преобразование квадратные скобки обозначения объекта

var plain = { 
    id: 1, 
    'items[A][Z]': 2, 
    'items[B]': false, 
    'items[C][][A]': 1 
} 

Я хочу, чтобы преобразовать объект, создав соответствующий вспомогательный объект (ы):

var result = { 
    id: 1, 
    items: { 
     A: {Z:2}, 
     B: false, 
     C: [ {A:1} ] 
    } 
} 

Насколько я знаю, это обычная практика, но я не могу найти больше ресурсов на эту тему. Как обычно называется так называемое и как лучше всего конвертировать plain в result?

Редактировать: Я обновил примеры с помощью Array. Это, по-видимому, связано, а также поддерживается body-parser экспресс.

+0

Почему downvote? –

ответ

2

Вы могли бы разделить путь и сократить путь, пройдя данный объект. Если объект не существует, создайте новое свойство с именем. Позже присвойте значение и удалите разделенное свойство.

var plain = { id: 1, 'items[A][Z]': 2, 'items[B]': false }; 
 

 
Object.keys(plain).forEach(function (k) { 
 
    var path = k.replace(/\[/g, '.').replace(/\]/g, '').split('.'), 
 
     last = path.pop(); 
 

 
    if (path.length) { 
 
     path.reduce(function (o, p) { 
 
      return o[p] = o[p] || {}; 
 
     }, plain)[last] = plain[k]; 
 
     delete plain[k]; 
 
    } 
 
}); 
 

 
console.log(plain);

ES6

var plain = { id: 1, 'items[A][Z]': 2, 'items[B]': false }; 
 

 
Object.keys(plain).forEach(k => { 
 
    var path = k.replace(/\[/g, '.').replace(/\]/g, '').split('.'), 
 
     last = path.pop(); 
 

 
    if (path.length) { 
 
     path.reduce((o, p) => o[p] = o[p] || {}, plain)[last] = plain[k]; 
 
     delete plain[k]; 
 
    } 
 
}); 
 

 
console.log(plain);

+0

Это очень полезно, спасибо! Теперь я пытаюсь реализовать пустые квадратные скобки ('[]') для создания массива (см. Обновленный вопрос) - но я застрял в возврате 'reduce', похоже, работает только с суб-объектами - вы бы дали мне намек? Или это должно быть сделано раньше, чем «уменьшить массив»? –

+1

Я предлагаю изменить систему на именованные свойства для объектов и чисел в скобках для массива, например 'plain.c [3]', где c - массив, а 3 - индекс массива, вы можете посмотреть [здесь ] (http://stackoverflow.com/questions/40131843/accessing-or-creating-nested-javascript-objects-with-string-key-without-eval) –

+0

То, что мне нужно, Данке! [JSFiddle] (https://jsfiddle.net/RienNeVaPlus/3bfLfdhn/) того, что я использую сейчас. –

1

Вы можете использовать reduce() и filter() вот так.

var plain = { 
 
    id: 1, 
 
    'items[A][Z]': 2, 
 
    'items[B]': false 
 
} 
 

 
var obj = {} 
 
var result = Object.keys(plain).reduce(function(r, e) { 
 
    if (e.match(/\[(.*?)\]/gi)) { 
 
    var keys = e.split(/\[(.*?)\]/gi).filter(e => e != ''); 
 
    keys.reduce(function(a, b, i) { 
 
     return (i != keys.length - 1) ? a[b] || (a[b] = {}) : a[b] = plain[e]; 
 
    }, obj) 
 
    } else { 
 
    obj[e] = plain[e]; 
 
    } 
 
    return r; 
 
}, obj) 
 

 
console.log(result)

Смежные вопросы