Преобразовать сгруппированный запрос в дерево объектов - PullRequest
1 голос
/ 11 июня 2019

Я хочу преобразовать результат запроса в объект дерева в формате js, каждое поле запроса добавляется в массив, например, ['field2', 'field3'] в файле js, поэтому серверная часть создает динамический запрос с ним, дерево должно быть создано слева направо, наиболее внешне по отношению к большинству внутренних полей (запрос также группируется по идентификатору полей), это запрос (помните, что поля являются динамическими, поэтому добавляется больше полей), последнее ветвь дерева должна быть величиной (которая тоже динамическая)

SELECT 
    T2.field2 as field2, T3.field3 as field3, SUM(quantity) AS quantity
FROM 
    table1 T1
    INNER JOIN
    table2 T2 ON T1.table2_id = T2.id
    INNER JOIN
    table3 T3 ON T1.table3_id = T3.id
WHERE
    AND T1.date = 20190611
GROUP BY T1.table2_id, T1.table3_id

это даст мне такой набор данных

'Group 1', 'Data 0', '9172'
'Group 1', 'Data 1', '789'
'Group 1', 'Data 22', '289'
'Group 1', 'Data 3', '254'
'Group 1', 'Data 4', '197'
'Group 1', 'Data 55', '173'
'Group 2', 'Data 0', '38'
'Group 2', 'Data 11', '3'
'Group 2', 'Data 4', '4'
'Group 3', 'Data 0', '807'
'Group 3', 'Data 1', '40'
'Group 3', 'Data 18', '4'
'Group 3', 'Data 2', '35'

Что мне нужно сделать, так это преобразовать его в нечто подобное.

[
  {
    field2: 'Group 1',
    data: [
      {
        field3: 'Data 0',
        data: [
          { quatity: 9172 },
        ],
      },
      {
        field3: 'Data 1',
        data: [
          { quatity: 789 },
        ],
      },
      {
        field3: 'Data 3',
        data: [
          { quatity: 289 },
        ],
      },
      {
        field3: 'Data 4',
        data: [
          { quatity: 197 },
        ],
      },
      {
        field3: 'Data 55',
        data: [
          { quatity: 173 },
        ],
      },
    ],
  },
  {
    field2: 'Group 2',
    data: [
      {
        field3: 'Data 0',
        data: [
          { quatity: 38 },
        ],
      },
      {
        field3: 'Data 11',
        data: [
          { quatity: 3 },
        ],
      },
      {
        field3: 'Data 4',
        data: [
          { quatity: 4 },
        ],
      },
    ],
  },
  {
    field2: 'Group 3',
    data: [
      {
        field3: 'Data 0',
        data: [
          { quatity: 807 },
        ],
      },
      {
        field3: 'Data 1',
        data: [
          { quatity: 40 },
        ],
      },
      {
        field3: 'Data 18',
        data: [
          { quatity: 4 },
        ],
      },
      {
        field3: 'Data 2',
        data: [
          { quatity: 35 },
        ],
      },
    ],
  },
]

Хитрость в том, что поля в запросе являются динамическими, поэтому мне нужно следить за тем, чтобы оно дошло до последнего поля в списке, поэтому, если у массива полей есть такие элементы, как ['field2', 'field3', 'field4'], а массив значений имеет массив как ['quantity', 'balance'] результат должен быть что-то вроде

[
  {
    field2: 'Group 1',
    data: [
      {
        field3: 'Data 0',
        data: [
          {
            field4: 'Last field,
            data: [
              { quantity: 3435, balance: 43.53 },
            ],
          },
          {
            field4: 'Last field,
            data: [
              { quantity: 234, balance: 241.53 },
            ],
          },
        ],
      },
    ],
  },
]

Как этого добиться?

1 Ответ

2 голосов
/ 11 июня 2019

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

var data = [['Group 1', 'Data 0', '9172'], ['Group 1', 'Data 1', '789'], ['Group 1', 'Data 22', '289'], ['Group 1', 'Data 3', '254'], ['Group 1', 'Data 4', '197'], ['Group 1', 'Data 55', '173'], ['Group 2', 'Data 0', '38'], ['Group 2', 'Data 11', '3'], ['Group 2', 'Data 4', '4'], ['Group 3', 'Data 0', '807'], ['Group 3', 'Data 1', '40'], ['Group 3', 'Data 18', '4'], ['Group 3', 'Data 2', '35']],
    keys = ['field2', 'field3'],
    values = ['quantity'],
    result = data.reduce((r, a) => {
        keys
            .reduce((q, k, i) => {
                var temp = q.find(o => o[k] === a[i]);
                if (!temp) q.push(temp = { [k]: a[i], data: [] });
                return temp.data;
            }, r)
            .push(Object.assign({}, ...values.map((k, i) => ({ [k]: a[keys.length + i] }))));
        return r;
    }, []);

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