Home > Enterprise >  how do convert the nested JSON to flatJSON
how do convert the nested JSON to flatJSON

Time:09-06

Here is the JSON actually I have

[
  {
    "heading": [
      {
        "name": "Heading 01",
        "Items": [
          {
            "name": "Item 01",
            "layers": [
              {
                "name": "layer01",
                "id": 4,
                "parent": 3,
                "droppable": false
              },
              {
                "name": "layer02",
                "id": 5,
                "parent": 3,
                "droppable": false
              }
            ],
            "id": 3,
            "parent": 2,
            "droppable": true
          }
        ],
        "id": 2,
        "parent": 1,
        "droppable": true
      }
    ],
    "id": 1,
    "parent": 0,
    "droppable": true
  }
]

I want my output to be flatJSON but I am not able get the result here is my code

let data =[
  {
    "heading": [
      {
        "name": "Heading 01",
        "Items": [
          {
            "name": "Item 01",
            "layers": [
              {
                "name": "layer01",
                "id": 4,
                "parent": 3,
                "droppable": false
              },
              {
                "name": "layer02",
                "id": 5,
                "parent": 3,
                "droppable": false
              }
            ],
            "id": 3,
            "parent": 2,
            "droppable": true
          }
        ],
        "id": 2,
        "parent": 1,
        "droppable": true
      }
    ],
    "id": 1,
    "parent": 0,
    "droppable": true
  }
]

var flatArray = [];
var flatObject = {};
  
for (var index = 0; index < data.length; index  ) {
  for (var prop in data[index]) {
  
    var value = data[index][prop];
  
    if (Array.isArray(value)) {
      for (var i = 0; i < value.length; i  ) {
        for (var inProp in value[i]) {
          flatObject[inProp] = value[i][inProp];
        }
      }
    } else {
        flatObject[prop] = value;
    }
  }
  flatArray.push(flatObject);
}

console.log(flatArray)

the output should be like this

[
  {
    "parent": 0,
    "id": 1,
    "text": "0",
    "droppable": true,
    
  },
  {
    "name": "Heading 01",
    "parent": 1,
    "id": 2,
    "text": "1",
    "droppable": true
  }{
    "name": "Item 01",
    "parent": 2,
    "id": 3,
    "text": "2",
    "droppable": true
  },
  {
    "name": "layer01",
    "parent": 3,
    "id": 4,
    "text": "3",
    "droppable": false
  },
  {
    "name": "layer02",
    "parent": 3,
    "id": 4,
    "text": "3",
    "droppable": false
  }
]

CodePudding user response:

Recursive approach:

const data = [{"id": 1,"parent": 0,"droppable": true,"heading": [{"name": "Heading 01","Items": [{"name": "Item 01","layers": [{"name": "layer01","id": 4,"parent": 3,"droppable": false},{"name": "layer02","id": 5,"parent": 3,"droppable": false}],"id": 3,"parent": 2,"droppable": true}],"id": 2,"parent": 1,"droppable": true}]}];
  
const iter = (data) => data.reduce((acc, obj) => {
    const entries = Object.entries(obj);
    const arrays = entries.filter(([, value]) => Array.isArray(value)); 
    const objWithoutArrays = entries
      .reduce((acc, [key, value]) => Array.isArray(value) 
        ? acc 
        : { ...acc, [key]: value }
      , {});
      
    acc.push(objWithoutArrays);
    acc.push(...arrays.flatMap(([, value]) => iter(value)));
    
    return acc;
}, []);

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

CodePudding user response:

One could come up with a recursive approach which targets specific array items by any wanted array's key/identifier which are going to be used by a destructuring assignment with default values and rest property.

The advantage of the destructuring is the separation and the direct access of all relevant data, the possible to be targeted array(s) and the rest of the currently processed data item.

function collectSpecificArrayItemsRecursively(data) {
  const result = [];

  if (Array.isArray(data)) {

    result
      .push(
        ...data
          .flatMap(collectSpecificArrayItemsRecursively)
      );
  } else {

    const {
      // destructuring into specific
      // arrays and the data's rest.
      heading = [], Items = [], layers = [], ...rest
    } = data;

    result
      .push(
        rest,
        ...heading
          .concat(Items)
          .concat(layers)
          .flatMap(collectSpecificArrayItemsRecursively),
      );    
  }
  return result;
}
const data = [{
  heading: [{
    name: "Heading 01",
    Items: [{
      name: "Item 01",
      layers: [{
        name: "layer01",
        id: 4,
        parent: 3,
        droppable: false
      }, {
        name: "layer02",
        id: 5,
        parent: 3,
        droppable: false
      }],
      id: 3,
      parent: 2,
      droppable: true
    }],
    id: 2,
    parent: 1,
    droppable: true
  }],
  id: 1,
  parent: 0,
  droppable: true
}];

console.log(
  collectSpecificArrayItemsRecursively(data)
);
.as-console-wrapper { min-height: 100%!important; top: 0; }

CodePudding user response:

here is my solution.

const c = (item: any) => "name" in item ? [{
  name: item.name,
  id: item.id,
  parent: item.parent,
  droppable: item.droppable
}] : []

function flat(item: any) {
  if ("heading" in item) {
    return c(item).concat(item.heading.flatMap(flat))
  }

  if ("Items" in item) {
    return c(item).concat(item.Items.flatMap(flat))
  }

  if ("layers" in item) {
    return c(item).concat(item.layers.flatMap(flat))
  }

  return c(item)
}

console.log(data.flatMap(flat))
  • Related