Генерация рекурсивных JSON из записей БД - PullRequest
0 голосов
/ 06 апреля 2020

Я работаю над чем-то уже несколько дней, но не могу понять. У меня есть таблица БД (с фиктивными данными), которая выглядит следующим образом:

enter image description here

На основе key и value I хочу сгенерировать json. field_id является родителем в структуре json. Но как я могу создать эту структуру в javascript?

Я уже пробовал это:

 let fields = [
    { id: 1, field_id: null, key: 'key1', value: 'value1'},
    { id: 2, field_id: 1, key: 'key2', value: 'value2'},
    { id: 3, field_id: 2, key: 'key3', value: 'value3'},
    { id: 4, field_id: 1, key: 'key4', value: 'value4'}
 ];

 let result = [];
 
fields.map(({key, value, id}) => {
    let obj = {}; obj[key] = value

    fields.forEach((f) => {
        if(f.field_id == id) {
            let obj2 = {}; obj2[f.key] = f.value

            obj = {...obj, ...obj2}
        }
    });

    result.push(obj);
  });
  
  console.log(result);

Но это, очевидно, не работает. Я думаю, мне нужна какая-то рекурсивная функция?

Ожидаемый результат:

[{
    "key1": [{
            "key2": [{
                "key3": "value3"
            }]
        },
        {
            "key4": "value4"
        }
    ]
}]

Ответы [ 2 ]

3 голосов
/ 06 апреля 2020

Вы можете использовать рекурсивную функцию вместо одноуровневой map().

Сначала отфильтруйте значения с помощью field_id === null, чтобы получить элементы root .

Затем получите его потомков, отфильтровав с помощью fields.filter(field => field.field_id === item.id) и примените функцию к каждому потомку.

let fields = [
    { id: 1, field_id: null, key: 'key1', value: 'value1'},
    { id: 2, field_id: 1, key: 'key2', value: 'value2'},
    { id: 3, field_id: 2, key: 'key3', value: 'value3'},
    { id: 4, field_id: 1, key: 'key4', value: 'value4'}
 ];
 
 
 const getNested  = (item) => {
 
    const children = fields.filter(field => field.field_id === item.id);
    return {
      [item.key] : children.length === 0 ? item.value : children.map(field => getNested(field))
    }
  
 }
 
 
 const nestedJSON = fields.filter(field => field.field_id === null).map(field => getNested(field))
 
 console.log(nestedJSON);

Надеюсь, это поможет.

1 голос
/ 06 апреля 2020

Вы можете выбрать один подход l oop и создать дерево.

Это решение принимает оба направления отношений между узлом к ​​родителю и родителем к узлу.

let fields = [{ id: 1, field_id: null, key: 'key1', value: null }, { id: 2, field_id: 1, key: 'key2', value: null }, { id: 3, field_id: 2, key: 'key3', value: 'value3' }, { id: 4, field_id: 1, key: 'key4', value: 'value4' }],
    tree = function (data, root) {
        var t = { keys: {} };
        data.forEach(({ id, field_id, key, value }) => {
            t[id] = t[id] || {};
            t[id][key] = value === null ? [] : value;
            t.keys[id] = key;
            t[field_id] = t[field_id] || {};
            let k = t.keys[field_id];
            t[field_id][k] = t[field_id][k] || [];
            t[field_id][k].push(t[id]);
        });
        return t[root].undefined;
    }(fields, null);

console.log(tree);
.as-console-wrapper { max-height: 100% !important; top: 0; }
...