javascriptarraysobjectreducehigher-order-functions

An elegant way to flatten an object


I am facing trival problem to flatten simple object with nested one inside.

Tried sollution fro SO, but it throws error:

const newWeather = Object.assign({}, ...function _flatten(o) { return [].concat(...Object.keys(o).map(k => typeof o[k] === 'object' ? _flatten(o[k]) : ({[k]: o[k]})))}({id: 1}))

// also tried these ones:

    console.log(Object.keys(weatherDetails).reduce((a, b, c) => {
        return Object.assign(a, {
            a: b
        })
    }, {})); 

// another one

let newWeather = Object.assign({}, (function() {
        var obj = {}
        for (var i = 0; i < Object.keys(weatherDetails).length; i++) {
            console.log(i, Object.keys(weatherDetails))
            obj[Object.keys(weatherDetails)] = weatherDetails[Object.keys(weatherDetails)]
        }
        return obj
    })())

Here is my object I need to flatten, so we need to turn this:

{ 
    temperature: null, 
    humidity: null, 
    pressure: null, 
    windspeed: null, 
    pollution: {
        PM1: 1,
        PM10: 2,
        PM25: 3
    }
}

Into this:

{ 
    temperature: null, 
    humidity: null, 
    pressure: null, 
    windspeed: null, 
    PM1: 1,
    PM10: 2,
    PM25: 3
}

Solution

  • Just merge and delete every child property that's an instanceof Object.

    let obj =
    { 
        temperature: null, 
        humidity: null, 
        pressure: null, 
        windspeed: null, 
        pollution: {
            PM1: 1,
            PM10: 2,
            PM25: 3,
    		pollution: 4
        }
    };
    
    function flatten(obj)
    {
    	obj = Object.assign({}, obj);
    	
    	for (let i in obj)
    		if (obj[i] instanceof Object)
    		{
    			obj = Object.assign(obj, obj[i]);
    
    			// Prevent deletion of property i/"pollution", if it was not replaced by one of the child object's properties
    			if (obj[i] === obj[i][i])
    				delete obj[i];
    		}
    	
    	return obj;
    }
    
    let obj_flattened = flatten(obj);
    console.log(obj_flattened);