Is there any way to rename js object keys using un

2019-01-22 01:22发布

问题:

I need to convert a js object to another object for passing onto a server post where the names of the keys differ for example

var a = {
    name : "Foo",
    amount: 55,
    reported : false,
    ...
    <snip/>
    ...
    date : "10/01/2001"
    } 

needs to turn into

a = {
  id : "Foo",
  total : 55,
  updated: false,
  ...
  <snip/>
  ... 
  issued : "10/01/2001"
  }

where I have lookup obj available for mapping all the keys

var serverKeyMap = {
    name : "id",
    amount : "total",
    reported : "updated",
     ...
    date : "issue"
    }

Is there a function available in underscore.js or jQuery that I can use that does this functionality?

thanks

回答1:

As far as I know there is no function built into either of these two libraries. You can make your own fairly easily, though: http://jsfiddle.net/T9Lnr/1/.

var b = {};

_.each(a, function(value, key) {
    key = map[key] || key;
    b[key] = value;
});


回答2:

I know you didn't mention lodash and the answers already solve the problem, but someone else might take advantage of an alternative.

As @CookieMonster mentioned in the comments, you can do this with _.mapKeys:

_.mapKeys(a, function(value, key) {
    return serverKeyMap[key];
});

And the fiddle: http://jsfiddle.net/cwkwtgr3/



回答3:

Similar to @pimvdb, you can also do it with a _.reduce:

_.reduce(a, function(result, value, key) {
    key = map[key] || key;
    result[key] = value;
    return result;
}, {});

Fiddle: http://jsfiddle.net/T9Lnr/39/



回答4:

You could copy the values to the new properties with standard JavaScript, and remove the original properties with omit, as follows:

a.id = a.name;
a.total = a.amount;
a.updated = a.reported;
a = _.omit(a, 'name', 'amount', 'reported');


回答5:

It's been solved here https://stackoverflow.com/a/30940370/1360897

var keyMapping = {'PropertyA': 'propertyA', ..., 'PropertyF': 'propertyNEW'}

and also a mapping of old and new values, like this

var valueMapping = {'Y': true, 'F': false}

And then using _.map and _.transform, you can transform the object, like this

var result = _.map(allItems, function(currentObject) {
    return _.transform(currentObject, function(result, value, key) {
        if (key === 'PropertyF' || key === 'PropertyG') {
            value = valueMapping(value);
        }
        result[keyMapping[key]] = value;
    });
});


回答6:

No there is no function in either library that explicitly renames keys. Your method is also the fastest (see jsperf tests.) Your best bet, if possible, is to refactor either the client side or server side code so the objects are the same.



回答7:

I have a transformation operator and would just like to apply it to all keys. I forked pimvdb's fiddle to produce a simple example. In this case it Capitalizes the key. And it dynamically builds the keymap, which I needed to assure works (thanks JSFiddle).

Here is the changed code:

var keymap = {};
_.each(a, function(value, key) {
    var oldkey = key;
    key = capitalize(key);
    keymap[oldkey] = key;
});
_.each(a, function(value, key) {
    key = keymap[key] || key;
    b[key] = value;
});

Fiddle: http://jsfiddle.net/mr23/VdNjf/



回答8:

// key_map: {old_name1: new_name1, ... }
function rename_keys(object, key_map, is_picked=false){
  keys = _.keys(key_map);
  new_keys = _.values(key_map);
  picked = _.pick(object, keys);
  renamed = _.object(new_keys, _.values(picked));
  if(is_picked) return renamed;

  return _.chain(object).omit(keys).extend(renamed).value();
}

This may be slower than above answers.



回答9:

Why don't you use this simple java script ? Value of any key:value pair should be string/number/Boolean.

<script type="text/javascript">    
    var serverKeyMap = {
        name : "id",
        amount : "total",
        reported : "updated"
    };

    var a = {
        name : "Foo",
        amount: 55,
        reported : false
    };

    var b={}; // b is object where you will get your output

    for(i in serverKeyMap) b[serverKeyMap[i]]=a[i];

    console.log(b); // It gives what you need.

</script>


回答10:

As user2387823 was saying above