简体   繁体   中英

Convert flat structure to object

In my attempts to make a generic CRUD system for Mongo DB and Mongoose I've ran into this challenge. When the user updates a record and I read the req.body the fields are returned in a flat structure. But some of my models have nested records, hence the dot notation.

I need to unwrap below into an object so I can pass it to Mongo DB.

I have:

var data = {
    'details.location.unit': undefined,
    'details.location.floor': undefined,
    'details.location.streetNumber': '67',
    'details.location.streetName': 'Brown St',
    'details.location.suburb': 'potts point',
    'details.location.postcode': 2011,
    'details.location.city': 'sydney',
    'details.location.state': 'nsw',
    'details.location.country': 'australia',
    'details.contact.phone': [ '(02) 2376 5678', '(02) 1234 5678' ],
    'details.contact.url': 'http://www.example.com',
    'details.contact.email': 'me@example.com'
}

And want to turn it into:

var data = {
    details:{
        location: {
            unit': undefined,
            floor': undefined,
            streetNumber': '67',
            streetName': 'Brown St',
            suburb': 'potts point'
        },

        contact: {
          phone': [ '(02) 2376 5678', '(02) 1234 5678' ],
          url: 'http://www.example.com',
          email: 'me@example.com',  
        }
    }
}

Notice the array in there as well. That needs to be JSON parsed. Not quite sure how to attack this one!

For another part of the project I used this function to access an object by string accessors. Perhaps it can be repurposed?

// @param {object} data
// @param {string} accessor e.g 'vehicles.cars.toyota'
// @return {*}
var getValueByAccessor = function (data, accessor) {

    var keys = accessor.split('.'),
        result = data;

    while (keys.length > 0) {
        var key = keys.shift();

        if (typeof result[key] !== 'undefined') {
            result = result[key];
        }

        else {
            result = null;
            break;
        }
    }

    return result;
}
var data = {
    'details.location.unit': undefined,
    'details.location.floor': undefined,
    'details.location.streetNumber': '67',
    'details.location.streetName': 'Brown St',
    'details.location.suburb': 'potts point',
    'details.location.postcode': 2011,
    'details.location.city': 'sydney',
    'details.location.state': 'nsw',
    'details.location.country': 'australia',
    'details.contact.phone': [ '(02) 2376 5678', '(02) 1234 5678' ],
    'details.contact.url': 'http://www.example.com',
    'details.contact.email': 'me@example.com'
}

var setNewValue = function (obj, chain, value) {
    var i = 0;
    while (i < chain.length - 1) {
        obj[chain[i]]=obj[chain[i]] || {};
        obj = obj[chain[i]];
        i++;
    }
    obj[chain[i]] = value;
};

var convertedObject={};
for(var a in data)if(data.hasOwnProperty(a)){
    var pathArr=a.split('.');
    var value=data[a];
    setNewValue (convertedObject, pathArr, value);
}

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