Leonardo Vinicius
Leonardo Vinicius

Reputation: 233

Transform object array into a tree data structure

I have some information saved in the database that I would like to display it in a structure defined by me.

When making a SELECT * FROM table is returned an array of information, as shown below. enter image description here

Follows the returned JSON to help.

[
{
    "IBX": "RJ1",
    "GroupName": "N/A",
    "ProductName": "Computer Hardware - Server Product",
    "POFName": "N/A"
},
{
    "IBX": "RJ1",
    "GroupName": "N/A",
    "ProductName": "Computer Hardware - Server Product",
    "POFName": "N/A"
},
{
    "IBX": "RJ1",
    "GroupName": "TESTE",
    "ProductName": "Storage Area Network Product",
    "POFName": "N/A"
},
{
    "IBX": "RJ1",
    "GroupName": "TESTE",
    "ProductName": "Storage Area Network Product",
    "POFName": "N/A"
},
{
    "IBX": "RJ1",
    "GroupName": "TESTE",
    "ProductName": "Storage Area Network Product",
    "POFName": "Teste_1"
},
{
    "IBX": "RJ1",
    "GroupName": "TESTE",
    "ProductName": "Storage Area Network Product",
    "POFName": "Teste_1"
},
{
    "IBX": "RJ1",
    "GroupName": "group_2",
    "ProductName": "Computer Hardware - Server Product",
    "POFName": "N/A"
},
{
    "IBX": "RJ1",
    "GroupName": "group_2",
    "ProductName": "Computer Hardware - Server Product",
    "POFName": "teste_2"
},
{
    "IBX": "RJ2",
    "GroupName": "TESTE",
    "ProductName": "Computer Hardware - Server Product",
    "POFName": "teste_3"
},
{
    "IBX": "RJ2",
    "GroupName": "TESTE",
    "ProductName": "Storage Area Network Product",
    "POFName": "N/A"
},
{
    "IBX": "RJ2",
    "GroupName": "TESTE",
    "ProductName": "Storage Area Network Product",
    "POFName": "N/A"
}
]

I would like to display the information as follows:

enter image description here

What I want is a four-level tree structure.

The first level is the IBX.

The second level is the group name (it is the user that defines it).

The third level is a junction between the product name and the user-given nickname.

The fourth level is the product configuration.

Below is what I tried to do, but I was unsuccessful.

PS.: Bold words represent json key

public transformInNestedList(products: ProductDatabase[]) {

var IBXs = products
  .map(x => x.IBX)
  .filter((v, i, s) => s.indexOf(v) === i);

var test = IBXs.reduce((a, c) => {
  var product_name = products
    .filter(x => x.IBX == c)
    .map(x => x.ProductName)
    .filter((v, i, s) => s.indexOf(v) === i);

  console.log(product_name)

  var group_name = products
    .filter(x => x.IBX == c)
    .map(x => x.GroupName)
    .filter((v, i, s) => s.indexOf(v) === i);

  return a.concat({
    IBX: products.find(x => x.IBX == c).IBX,
    GROUP_NAMES: group_name.reduce((a2, c2) => a2.concat({
      GROUP_NAME: products.find(x => x.IBX == c && x.GroupName == c2).GroupName,
      PRODUCTS: product_name.reduce((a3, c3) => a3.concat({
        PRODUCT_NAME: products.find(x => x.IBX == c && x.ProductName == c3).ProductName,
        ATTRIBUTES: products.filter(x => x.IBX == c && x.ProductName == c3).reduce((a4, c4) => a4.concat({
          POE: c4.POE,
          ATTRIBUTE: c4.Attributes,
          ID: c4.id,
          times: c4.times,
          Price: c4.Price
        }), [])
      }), [])
    }), [])
  })
}, []);

Upvotes: 0

Views: 153

Answers (2)

Taher Ghulam Mohammed
Taher Ghulam Mohammed

Reputation: 399

Will this work:

const jsontest = [{
    "IBX": "RJ1",
    "GroupName": "N/A",
    "ProductName": "Computer Hardware - Server Product",
    "POFName": "N/A"
  },
  {
    "IBX": "RJ1",
    "GroupName": "N/A",
    "ProductName": "Computer Hardware - Server Product",
    "POFName": "N/A"
  },
  {
    "IBX": "RJ1",
    "GroupName": "TESTE",
    "ProductName": "Storage Area Network Product",
    "POFName": "N/A"
  },
  {
    "IBX": "RJ1",
    "GroupName": "TESTE",
    "ProductName": "Storage Area Network Product",
    "POFName": "N/A"
  },
  {
    "IBX": "RJ1",
    "GroupName": "TESTE",
    "ProductName": "Storage Area Network Product",
    "POFName": "Teste_1"
  },
  {
    "IBX": "RJ1",
    "GroupName": "TESTE",
    "ProductName": "Storage Area Network Product",
    "POFName": "Teste_1"
  },
  {
    "IBX": "RJ1",
    "GroupName": "group_2",
    "ProductName": "Computer Hardware - Server Product",
    "POFName": "N/A"
  },
  {
    "IBX": "RJ1",
    "GroupName": "group_2",
    "ProductName": "Computer Hardware - Server Product",
    "POFName": "teste_2"
  },
  {
    "IBX": "RJ2",
    "GroupName": "TESTE",
    "ProductName": "Computer Hardware - Server Product",
    "POFName": "teste_3"
  },
  {
    "IBX": "RJ2",
    "GroupName": "TESTE",
    "ProductName": "Storage Area Network Product",
    "POFName": "N/A"
  },
  {
    "IBX": "RJ2",
    "GroupName": "TESTE",
    "ProductName": "Storage Area Network Product",
    "POFName": "N/A"
  }
];

function createProductName(nodes) {
  const productNames = [];
  const exists = {};
  nodes.forEach(n => {
    if (!exists[n.ProductName + n.POFName]) {
      productNames.push({
        ProductName: n.ProductName,
        'POF NAME': n.POFName
      })
    }
    exists[n.ProductName + n.POFName] = true;
  });
  return productNames;
}

function createGrpNames(nodes) {

  const groupNames = [];
  const grpNm = Array.from(new Set(nodes.map(j => j.GroupName)));
  grpNm.forEach(n => groupNames.push({
    GroupName: n,
    ProductNames: createProductName(nodes.filter(js => js.GroupName === n))
  }));
  return groupNames;
}

function start() {
  const hierarchy = [];
  const ibx = Array.from(new Set(jsontest.map(j => j.IBX)));
  ibx.forEach(ib => hierarchy.push({
    IBX: ib,
    GroupNames: createGrpNames(jsontest.filter(js => js.IBX === ib))
  }));

  console.log(JSON.stringify(hierarchy));
}
start();

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386512

You could create a nested structure which takes an array of keys in the wanted order and groups the items.

var data = [{ IBX: "RJ1", GroupName: "N/A", ProductName: "Computer Hardware - Server Product", POFName: "N/A" }, { IBX: "RJ1", GroupName: "TESTE", ProductName: "Storage Area Network Product", POFName: "N/A" }, { IBX: "RJ1", GroupName: "TESTE", ProductName: "Storage Area Network Product", POFName: "Teste_1" }, { IBX: "RJ1", GroupName: "group_2", ProductName: "Computer Hardware - Server Product", POFName: "N/A" }, { IBX: "RJ1", GroupName: "group_2", ProductName: "Computer Hardware - Server Product", POFName: "teste_2" }, { IBX: "RJ2", GroupName: "TESTE", ProductName: "Computer Hardware - Server Product", POFName: "teste_3" }, { IBX: "RJ2", GroupName: "TESTE", ProductName: "Storage Area Network Product", POFName: "N/A" }],
    keys = ['IBX', 'GroupName', 'ProductName', 'POFName'],
    result = data
        .reduce((r, o) => {
            keys.reduce((q, k) => {
                var temp = (q.children = q.children || []).find(t => t[k] === o[k]);
                if (!temp) q.children.push(temp = { [k]: o[k] });
                return temp;
            }, r);
            return r;
        }, { children: [] })
        .children;

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

Upvotes: 2

Related Questions