Convert returned JSON Object Properties to (lower

2019-02-03 00:29发布

I have JSON returned from an API like so:

Contacts: [{ GivenName: "Matt", FamilyName:"Berry" }]

To keep this consistent with my code style (camelCase - lower case first letter) I want to transform the array to produce the following:

 contacts: [{ givenName: "Matt", familyName:"Berry" }]

Whats the easiest/best way to do this? create a new Contact object and iterate over all the contacts in the returned array?

var jsonContacts = json["Contacts"],
    contacts= [];

_.each(jsonContacts , function(item){
    var contact = new Contact( item.GivenName, item.FamilyName );
    contacts.push(contact);
});

or can I map the original or transform it somehow?

13条回答
The star\"
2楼-- · 2019-02-03 00:38

Well I took up the challenge and think I figured it out:

var firstToLower = function(str) {
    return str.charAt(0).toLowerCase() + str.slice(1);
};

var firstToUpper = function(str) {
    return str.charAt(0).toUpperCase() + str.slice(1);
};

var mapToJsObject = function(o) {
    var r = {};
    $.map(o, function(item, index) {
        r[firstToLower(index)] = o[index];
    });
    return r;
};

var mapFromJsObject = function(o) {
    var r = {};
    $.map(o, function(item, index) {
        r[firstToUpper(index)] = o[index];
    });
    return r;
};


// Map to
var contacts = [
    {
        GivenName: "Matt",
        FamilyName: "Berry"
    },
    {
        GivenName: "Josh",
        FamilyName: "Berry"
    },
    {
        GivenName: "Thomas",
        FamilyName: "Berry"
    }
];

var mappedContacts = [];

$.map(contacts, function(item) {
    var m = mapToJsObject(item);
    mappedContacts.push(m);
});

alert(mappedContacts[0].givenName);


// Map from
var unmappedContacts = [];

$.map(mappedContacts, function(item) {
    var m = mapFromJsObject(item);
    unmappedContacts.push(m);
});

alert(unmappedContacts[0].GivenName);

Property converter (jsfiddle)

The trick is handling the objects as arrays of object properties.

查看更多
戒情不戒烟
3楼-- · 2019-02-03 00:41

Took the challenge with lodash and some es6+ features Here is my implementation with the reduce function.

function deeplyToCamelCase(obj) {
  return _.reduce(obj, (camelCaseObj, value, key) => {
    const convertedDeepValue = _.isPlainObject(value) || _.isArray(value)
      ? deeplyToCamelCase(value)
      : value;
    return { ...camelCaseObj, [_.camelCase(key)] : convertedDeepValue };
  }, {});
};
查看更多
迷人小祖宗
4楼-- · 2019-02-03 00:44

If you would use lodash instead of underscore, this would do:

_.mapKeys(obj, (v, k) => _.camelCase(k))

This would convert both TitleCase and snake_case to camelCase. Note that it is not recursive though.

查看更多
孤傲高冷的网名
5楼-- · 2019-02-03 00:44

I needed a generic method that accepted an array or object. This is what I'm using (I borrowed KyorCode's firstToLower() implementation):

function convertKeysToCamelCase(obj) {
    if (!obj || typeof obj !== "object") return null;

    if (obj instanceof Array) {
        return $.map(obj, function(value) {
            return convertKeysToCamelCase(value);
        });
    }

    var newObj = {};
    $.each(obj, function(key, value) {
        key = key.charAt(0).toLowerCase() + key.slice(1);
        if (typeof value == "object" && !(value instanceof Array)) {
          value = convertKeysToCamelCase(value);
        }
        newObj[key] = value;
    });

    return newObj;
};

Example calls:

var contact = { GivenName: "Matt", FamilyName:"Berry" };

console.log(convertKeysToCamelCase(contact));
// logs: Object { givenName="Matt", familyName="Berry"}

console.log(convertKeysToCamelCase([contact]));
// logs: [Object { givenName="Matt", familyName="Berry"}]

console.log(convertKeysToCamelCase("string"));
// logs: null

console.log(contact);
// logs: Object { GivenName="Matt", FamilyName="Berry"}
查看更多
The star\"
6楼-- · 2019-02-03 00:44

This is my take; more readable and with less nesting than brandoncode's implementation, and with more room for handling edge cases like Date (which isn't handled, by the way) or null:

function convertPropertiesToCamelCase(instance) {
    if (instance instanceof Array) {
        var result = [];

        for (var i = 0; i < instance.length; i++) {
            result[i] = convertPropertiesToCamelCase(instance[i]);
        }

        return result;
    }

    if (typeof instance != 'object') {
        return instance;
    }

    var result = {};

    for (var key in instance) {
        if (!instance.hasOwnProperty(key)) {
            continue;
        }

        result[key.charAt(0).toLowerCase() + key.substring(1)] = convertPropertiesToCamelCase(instance[key]);
    }

    return result;
}
查看更多
祖国的老花朵
7楼-- · 2019-02-03 00:46

Thanks other I do this (recursive function with lodash and ES6):

import { camelCase } from 'lodash';

const camelizeKeys = (obj) => {
  if (Array.isArray(obj)) {
    return obj.map(v => camelizeKeys(v));
  } else if (obj !== null && obj.constructor === Object) {
    return Object.keys(obj).reduce(
      (result, key) => ({
        ...result,
        [camelCase(key)]: camelizeKeys(obj[key]),
      }),
      {},
    );
  }
  return obj;
};

Test:

const obj = {
  'FirstName': 'John',
  'LastName': 'Smith',
  'BirthDate': new Date(),
  'ArrayTest': ['one', 'TWO', 3],
  'ThisKey': {
    'This-Sub-Key': 42
  }
}

console.log(JSON.stringify(camelizeKeys(obj)))

Output:

{  
   "firstName": "John",
   "lastName": "Smith",
   "birthDate": "2018-05-31T09:03:57.844Z",
   "arrayTest":[  
      "one",
      "TWO",
      3
   ],
   "thisKey":{  
      "thisSubKey": 42
   }
}
查看更多
登录 后发表回答