简体   繁体   English

有什么方法可以使用 underscore.js 重命名 js object 键

[英]Is there any way to rename js object keys using underscore.js

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我需要将 js object 转换为另一个 object 以传递到服务器帖子,例如,键的名称不同

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? underscore.js 中是否有可用的 function 或 jQuery 我可以使用它来执行此功能?

thanks谢谢

I know you didn't mention lodash and the answers already solve the problem, but someone else might take advantage of an alternative.我知道您没有提到lodash并且答案已经解决了问题,但其他人可能会利用替代方案。

As @CookieMonster mentioned in the comments, you can do this with _.mapKeys :正如评论中提到的@CookieMonster,您可以使用_.mapKeys执行此_.mapKeys

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

And the fiddle: http://jsfiddle.net/cwkwtgr3/和小提琴: http : //jsfiddle.net/cwkwtgr3/

Similar to @pimvdb, you can also do it with a _.reduce :与@pimvdb 类似,您也可以使用_.reduce

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

Fiddle: http://jsfiddle.net/T9Lnr/39/小提琴: http : //jsfiddle.net/T9Lnr/39/

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/ .不过,您可以相当容易地制作自己的: http : //jsfiddle.net/T9Lnr/1/

var b = {};

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

You could copy the values to the new properties with standard JavaScript, and remove the original properties with omit , as follows:您可以使用标准 JavaScript 将值复制到新属性,并使用omit删除原始属性,如下所示:

a.id = a.name;
a.total = a.amount;
a.updated = a.reported;
a = _.omit(a, 'name', 'amount', 'reported');
// 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.这可能比上述答案慢。

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.我分叉了 pimvdb 的小提琴来产生一个简单的例子。 In this case it Capitalizes the key.在这种情况下,它会将密钥大写。 And it dynamically builds the keymap, which I needed to assure works (thanks JSFiddle).并且它动态构建键映射,我需要它来确保工作(感谢 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/小提琴: http : //jsfiddle.net/mr23/VdNjf/

It's been solved here https://stackoverflow.com/a/30940370/1360897这里已经解决了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然后使用_.map和_.transform,就可以对对象进行变换,像这样

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;
    });
});

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.您的方法也是最快的(请参阅jsperf 测试。)如果可能,您最好的选择是重构客户端或服务器端代码,以便对象相同。

Why don't you use this simple java script ?你为什么不使用这个简单的java脚本? 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>

As user2387823 was saying above 👆 using omit is a great option.正如 user2387823上面所说的 👆 使用omit是一个不错的选择。 For example you could write something like this例如你可以写这样的东西

function updateObjKey(obj, currentKey, newKey) {
    var keyValue = obj[currentKey];
    obj = _.omit(obj, [currentKey]);
    obj[newKey] = keyValue;
    return obj;
  }

this ES2015/2017 version 🧙‍♂️这个 ES2015/2017 版本🧙‍♂️

 function objectMap(source,keyMap) { return Object.entries(keyMap).reduce((o,[key , newKey]) => { o[newKey]=source[key] return o;},{}) } const obj = { name : "Foo", amount: 55, reported : false, date : "10/01/2001" } const serverKeyMap = { name : "id", amount : "total", reported : "updated", date : "issue" } const result = objectMap(obj,serverKeyMap); console.log('🎬 =>' , result);

[Object.entries][1] is es2017 feture will return object key and value as array [Object.entries][1]是 es2017 feture 将对象键和值作为数组返回

[["name", "id"],["amount", "total"],...]

You really don't need underscore/lodash for this ... nowadays anyways (I realize the question was asked 9 years ago, but this question is (still) ranked highly in search results and I came across it today :-) )你真的不需要下划线/lodash ......现在无论如何(我意识到这个问题是 9 年前提出的,但这个问题(仍然)在搜索结果中排名很高,我今天遇到了它 :-) )

Here's another plain ES2015/2017 version that I like, inspired by @malbarmavi's answer (there's probably a bunch of other plain JS functions out there, but I didn't come across any others in my brief search):这是我喜欢的另一个简单的 ES2015/2017 版本,灵感来自@malbarmavi 的答案(那里可能有很多其他普通的 JS 函数,但我在简短的搜索中没有遇到任何其他函数):

// A general key transform method. Pass it a function that accepts the old key and returns
// the new key.
//
// @example
//   obj = transformKeys(obj, (key) => (
//    key.replace(/\b(big)\b/g, 'little')
//  ))
export function transformKeys(source, f) {
  return Object.entries(source).reduce((o, [key, value]) => {
    o[f(key) || key] = value
    return o
  }, {})
}
 
// Provide an object that maps from old key to new key
export function rekeyObject(source, keyMap) {
  transformKeys(source, key => keyMap[key])
}

Using underscore omit and spread operator.使用下划线omit和展开运算符。

a = _.omit({
  ...a,
  id: a.name,
  total: a.amount,
  updated: a.reported,
}, ['name', 'amount', 'reported']);

Key assignments below spread operator loads new keys and omit omits the old ones.展开运算符下面的键分配加载新键并省略旧键。

You can create your new custom function :您可以创建新的自定义函数:

lodash.rename = function(obj, keys, newKeys) {
  keys.map((key, index) => {
    if(lodash.includes(lodash.keys(obj), key)) {
      obj[newKeys[index]] = lodash.clone(obj[key], true);
      delete obj[key];
    }
  });
  return obj;
};

Or else if you want to edit only one keyName:否则,如果您只想编辑一个 keyName:

lodash.rename = function(obj, key, newKey) {
    if(lodash.includes(lodash.keys(obj), key)) {
      obj[newKeys[index]] = lodash.clone(obj[key], true);
      delete obj[key];
    }
  return obj;
};

I referred the lodash documentation ans found mapKeys https://lodash.com/docs/4.17.15#mapKeys我参考了 lodash 文档并找到了mapKeys https://lodash.com/docs/4.17.15#mapKeys

_.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) {
  return key + value;
});
// => { 'a1': 1, 'b2': 2 }

this perfectly renames the keys and return an object containing the modified desirable object这完美地重命名键并返回一个包含修改后的所需对象的对象

Using lodash使用 lodash

var obj = _.renameKeys( { 1 : "Geeks",  
            2 : "Computer_Science_Portal" }, 
            { 1 : "g", 2 : "c" }); 

so in your case, you want to apply the serverKeyMap onto object a:所以在你的情况下,你想将 serverKeyMap 应用到 object a 上:

var obj = _.renameKeys(a, serverKeyMap);

from https://www.geeksforgeeks.org/lodash-_-renamekeys-method/来自https://www.geeksforgeeks.org/lodash-_-renamekeys-method/

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM