简体   繁体   中英

Transform grouped query into Object tree

I want to transform the result of a query to a tree object in js, each field of the query is beign added in an array like ['field2', 'field3'] in the js file, so the back end create the dynamic query with it, the tree must be created from left to right most external to most internal field (the query is also being grouped by the id of the fields), this is the query (remember, the fields are dynamic so more fields are added), the last branch of the tree should be the quantities (wich are dynamic too)

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

this will give me a set of data like this

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

What i need to do is to trasform it to somethig like this.

[
  {
    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 },
        ],
      },
    ],
  },
]

The trick here is that the fields in the query are dynamic so i need to keed looking until it reach the last field in the list, so if the field array have a items like ['field2', 'field3', 'field4'] and the array of values have an array like ['quantity', 'balance'] the result should be something like

[
  {
    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 },
            ],
          },
        ],
      },
    ],
  },
]

How could achieve this?

You could take a combined approach by using the keys and values array and look for same objects.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM