Home > Software engineering >  Flatten nested JSON second level only
Flatten nested JSON second level only

Time:10-05

I have my JSON structured like this

var data = var data = [{"id": 451, "title": {    "rendered": "title1" }, "acf": {    "floor": "6",    "business": [       "business"    ],    "status": {       "value": "null",       "label": "Määramata"    },    "suund": "",    "area": {       "value": "full",       "label": "Terve korrus"       },       "suurus": "",       "tookohad": "",    }, },]; 

I need to flatten acf to get it like this without acf nesting.

var data = [
  {
"id": 451,
"title": {
   "rendered": "Title 1"
},
   "floor": "6",
   "business": [
      "business"
   ],
   "status": {
      "value": "null",
      "label": "Määramata"
   },
   "suund": "",
   "area": {
      "value": "full",
      "label": "Full"
      },
      "size": "",
},
];

I tried to use this function

function flat(source, target) {
Object.keys(source).forEach(function (k) {
    if (source[k]!== null && typeof source[k] === 'object') {
        flat(source[k], target);
        return;
    }
    target[k] = source[k];
});flatObject = {};flat(data, flatObject);console.log(flatObject);

But it flattens everything. I need to pick stuff out of acf but keep elements with id separate.

CodePudding user response:

You can easily use Destructuring assignment

const data = [{
  "id": 451,
  "title": {
    "rendered": "title1"
  },
  "acf": {
    "floor": "6",
    "business": ["business"],
    "status": {
      "value": "null",
      "label": "Määramata"
    },
    "suund": "",
    "area": {
      "value": "full",
      "label": "Terve korrus"
    },
    "suurus": "",
    "tookohad": "",
  },
}, ];

function flat(source, target) {
  const {
    id,
    ...rest
  } = source //What you dont want flattened
  if (id)
    target['id'] = id
  Object.keys(rest).forEach(function(k) {
    if (source[k] !== null && typeof source[k] === 'object') {
      flat(source[k], target);
      return;
    }
    target[k] = source[k];
  });
}
const flatObject = {};
flat(data, flatObject);
console.log(flatObject);

CodePudding user response:

You can do the following:

const flattenData = {
  ...data,
  acf: undefined,
  ...data.acf
};
delete flattenData['acf'];

This method chains some destructuring assignments. First - the ...data - we copy all the data in the first level. Then in the new object we overwrite acf with undefined. This reduces the memory footprint. At last we overwrite/copy the complete object of data.acf, thus flatten the array in the way you want.

If you can live with the acf: undefined in the array, you can remove the delete flattenData['acf'] and make it a bit faster.

CodePudding user response:

As I understand what you want to achieve is this: ( I improved the example so that you can work even on an array of objects )

var data = [{"id": 451, "title": {    "rendered": "title1" }, "acf": {    "floor": "6",    "business": [       "business"    ],    "status": {       "value": "null",       "label": "Määramata"    },    "suund": "",    "area": {       "value": "full",       "label": "Terve korrus"       },       "suurus": "",       "tookohad": "",    }, },]; 

function flat(source) {
  let result = source.map(el => {
    let noAcf = {}
    Object.keys(el).forEach(key => {
      if(key === "acf"){
        noAcf = {...noAcf, ...el[key]}
      } else {
        noAcf[key]=el[key]
      }
    })
    return noAcf
  })
  return result
}


const flatObjectsList = flat(data);
console.log(flatObjectsList);

  • Related